使用编程语言coding,只是把语言当作工具使用,只为解决问题,不求甚解,对语言的理解不深入、不细致,忘的自然也快。
正如偶尔密集使用Python,放下、重又拾起曾经用过的、熟悉的语言知识,学的快、熟悉的快、忘的也快。
基本的知识体系还在、大的知识点虽还记得,一些细节还要重新回忆、查找,这也许就是熟能生巧。
暂立此文以记录之,方便查询,不断更新,减少网络查询时间,形成模块,以求减少回忆的时间。

https://peps.python.org/pep-0008/ -- PEP 8 – Style Guide for Python Code】


>>> import this
The Zen of Python, by Tim Peters   python哲学/python之禅

Beautiful is better than ugly.    优美胜于丑陋
Explicit is better than implicit.  显式胜于隐式(明了胜于晦涩)
Simple is better than complex.    简单胜于复杂 
Complex is better than complicated.  复杂胜于凌乱
Flat is better than nested.      扁平胜于嵌套
Sparse is better than dense.      间隔胜于紧凑  
Readability counts.          足够的可读性
Special cases aren't special enough to break the rules.   特例也不足以打破此规则
Although practicality beats purity.   虽然实用性
Errors should never pass silently.    错误不应被忽视
Unless explicitly silenced.        除非确认要忽视
In the face of ambiguity, refuse the temptation to guess.   存在多种可能时,不要去猜测
There should be one-- and preferably only one --obvious way to do it.   应该只有一个,最好的只有一个,明显的解决方案
Although that way may not be obvious at first unless you're Dutch.  虽然这并不容易,因为你不是python之父
Now is better than never.   当下比曾经要好
Although never is often better than *right* now.   尽管曾经总是比立即动手要好
If the implementation is hard to explain, it's a bad idea.    如果这个实现不容易解释,这不是个好主意
If the implementation is easy to explain, it may be a good idea.  如果这个实现容易解释,这可能是个好主意
Namespaces are one honking great idea -- let's do more of those!  命名空间是个好主意,应该多用


DRY,Don't Reinvent the Wheel -- 不要重复发明轮子
DRY是指Don't Repeat Yourself,特指在程序设计以及计算中避免重复代码,因为这样会降低灵活性、简洁性,并且可能导致代码之间的矛盾。
《The Pragmatic Programmer》对这一思想做了很好的阐述。
把一切重复的代码抽象出来。最主要的原因是很好维护,当需要改动时只需要改动一次。简洁比简单更重要,维护成本高低的决定因素。
把固定的部分和变化的部分分离出来。固定的部分分离有利于代码复用,变换的部分分离,在变换发生时容易修改替换。
代码复用的层次:函数级别复用、对象级别复用、接口级别的、类库级别复用、框架级别复用。


>> Python版本 

# python -v
# python
# sys.version


Python插件安装

## 使用whl安装
pip install wheel   #安装wheel插件
pip install *.whl   #安装whl文件

## 直接安装
pip install *** == version      #安装指定版本的的插件

## 使用国内镜像安装,加快速度
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple *** == version

## SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED]
## 使用 --trusted-host 参数
pip --trusted-host pypi.tuna.tsinghua.edu.cn/simple install *** -i https://pypi.tuna.tsinghua.edu.cn/simple

## 国内镜像列表
# 清华大学:https://pypi.tuna.tsinghua.edu.cn/simple
# 中国科学技术大学 : https://pypi.mirrors.ustc.edu.cn/simple
# 豆瓣:http://pypi.douban.com/simple/
# 阿里云:http://mirrors.aliyun.com/pypi/simple/

0. 特别注意语言保留关键字的使用,有用过使用关键字命名的python文件吗?试试看,会让你酸爽的。

1. Python中的“_”,"__"  【】
    1)_, 交互解释器中最后一次执行语句的返回结果
      _用作被丢弃 的名称,不作特殊使用
        以“_”开头,弱内部标识,指私有变量或方法,定义为类内部变量或方法,只能在类内部访问。使用from module_name  import * 导入时不会被导入,但可以使用import module_name调用。
        a name prefixed with an underscore (e.g. _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). It should be considered an implementation detail and subject to change without notice.
    2)以"_"结尾,是为了使用python关键字作为变量名,在结尾添加"_"以避免与python关键字的命名冲突。
    3)"__A", 避免被子类重写,只能在类内部调用。模块内的成员,表示私有成员,外部无法直接调用。使用dir()命令显示此类方法,显示为 类名__A
    4)"__A__", 表示A是一个只能被python调用的方法 或 用作特殊用途。  magic methods??

2. Self
    Python中对象方法的定义很怪异,第一个参数一般都命名为self(相当于其它语言的this),用于传递对象本身,而在调用的时候则不必显式传递,系统会自动传递。

3. Super
    在super机制里可以保证公共父类仅被执行一次。super就是用来调用所继承基类的方法,只是多继承时公共仅被 执行一次,而父类方法 的用法,每一次申明都会调用一次父类。
    super(type[, object-or-type])  Return the superclass of type. If the second argument is omitted the super object returned is bound. If the second argument is an object, isinstance(obj, type) must be true. If the second argument is a type, issubclass(type2, type)       must be true. super() only works for new-style classes. A typical use for calling a cooperative superclass method。

4. __init__
    作用是初始化已实例化后的对象, 实例化子类时,会自动隐式调用超类中已定义的__init__。如果子类重写了__init__,实例化子类时,则不会隐式的再去调用超类中已定义的__init__,因此需要显示调用父类方法,即super(子类名,self). __init__

5. MRO
    MRO(Method Resolution Order),方法解析顺序。 【http://python.jobbole.com/85685/】
    Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多问题,比如二义性,Python中一切皆引用,这使得他不会像C++一样使用虚基类处理基类对象重复的问题,但是如果父类存在同名函数的时候还是会产生二义性,Python中处理这种问题的方法就是MRO。

6. system path
    python的搜索模块的路径集,list。【https://docs.python.org/3/using/cmdline.html】

import sys
sys.path.append('c:\\mypythonlib')

# current exe file path
sys.argv[0]   # references path

import os

os.curdir     # references path
# current folder path
os.getcwd()
os.path.abspath(".")
os.path.abspath(os.curdir)

7. @ decorator 修饰符/装饰器,将下一行的类或函数作为参数传递到修饰行,因此@修饰的函数必须有参数,而被传递的类或函数将无法单独执行
   装饰器,即将函数作为参数传入。概念:函数闭包    

######## basic
def t1(i):
    print(i.__name__)
    print(i)
    print(i())

@t1
def t2():
    print(1)
    return 2

>>>>>>>>>>    # t1(t2)
t2
<function t2 at 0x0000017694D4D4C0>
1
2

######## more
def t1(a):          # if there is no parameter "a": TypeError: t1() takes 0 positional arguments but 1 was given
    print(1)

def t2(b):
    print(2)

@t1
@t2                   
def t3():           # if there is no t3: SyntaxError: unexpected EOF while parsing
    print(3)        # t3(): TypeError: 'NoneType' object is not callable

>>>>>>>>>>>>    # t1(t2(t3)).   
#  @t1: @t2 is t1's parameter
#  @t2: t3 is t2's parameter, interact
2
1

######## more
def t1(i):
    print(i())

@t1
def t2():
    print(1)
    return 2

>>>>>>>>>>>>    # t1(t2)
#  print(t2()) -- 1 2 
1
2

############## decorator
def decorator(f):
##    return f
    def result(a,b,c):
        f(a,b,c)
    return result

@decorator
def func(a,b,c):
    print(a,b,c)

func(1,2,3)

>>>  # decorator(func())
# result = decorate(func(1,2,3))
# result(1,2,3) 
# func(1,2,3)
1 2 3

8. python2.7和python3.5的区别
   1)print 和 print()
   2) /: int 和 float
   3) BIF及functools的引用
   4)iter的next方法实现(2.7__next__, 3.X next())

9.string, tuble, list的slice操作分为正向和逆向,因此表达分为
  1)开始:结束:步长 (步长可以省略,默认值为1),其中的步长与开始与结束的方向要一致,即相同的正负值 
  2)开始::步长,此时的遍历只能正向进行到结束(1)或逆向进行到开始(-1),而不能循环进行
  3)slice结束值为开区间,也就是计算中结束值不在其中
       a = [1,2,3] => a[0:3:1] => a[-1:-4:-1] 

10.using Excel

import xlrd
import xlwt

#read
rd = xlrd.open_workbook(filename)  #read file
sh = rd.sheets()[0]   #get sheet data
nrow = sh.nrows  #get row number
row = sh.row(n)  #get row content
cel = row[i].value #get cell value

#write
wr = xlwt.Workbook()    #get file
sh = wr.add_sheet(sheetname,Formate)  #add new sheet with format

sh.write(rowN,columnN,value)
wr.save(filename)

11. __name__ == "__main__"
     1) 直接执行文件,则 __name__指向文件中的__main__,会执行__main__中的所有内容
     2) import该文件时,则__name__指向引用文件本身,只会执行引用文件自身,不会执行__main__中的内容

def test():
    return lambda x,y: x+ y

print(test()(5,6))

if __name__ == "__main__":
    print("This is test: ", test())
    print(__name__)
    print(test()(1,2))
#直接执行
11
This is test:  <function test.<locals>.<lambda> at 0x00000000031D3510>
__main__
3

import t1
from functools import reduce

print("This is Main test: ", t1.test()(8,9))
print(t1.__name__)
#引用文件
11
This is Main test:  17
t1

12. map, filter, reduce
     都是通过函数对迭代器进行运算,在py3 map和filter生成为对像,因此输出要用list就行转化;而reduce不能直接使用,需要在functools中引入
    1) map: 对迭代器中的每个元素进行函数运算,并输出map对像,使用list转化后即可输出
    2) filter: 按函数对迭代器中的每个元素进行筛选,并输出filter对像,使用list转化后即可输出
    3) reduce: 需要两个参数,将迭代器中的元素从左至右两两按函数进行运算,输出最终值

from functools import reduce

print(list(map(lambda x: x**2,[1,2,3,4,5])))
print(list(filter(lambda x: x%2 == 0, [1,2,3,4,5])))
print(reduce(lambda x,y: x*y,[1,2,3,4,5]))
#输出结果
[1, 4, 9, 16, 25]
[2, 4]
120

13. set: Build an unordered collection of unique elements. -- 可以使用set进行去除重复

14. list转字符串: ''.join(list)  -- 其中,‘’为分隔符,list中的每个元素应为字符串

15. python函数参数中的 * 和 **

def t_tuple(*i):       # * 动态参数,以元组方式展示; * 以Tuple形式传递任意个无名参数
    print(i)

t_tuple(1,2,3)


>>>
(1, 2, 3)
-------------------------------------------------------------------
def t_dict(**i):       # ** 动态参数,以字典方式展示;  ** 以Dict形式传递任意个有名参数
    print(i)
    print(i.keys())
    print(i.values())

t_dict(a=1,b=2,c=3) 

>>>
{'a': 1, 'b': 2, 'c': 3}
dict_keys(['a', 'b', 'c'])
dict_values([1, 2, 3])

16. from . import sessions
     “ . ” 指当前文件夹里的初始化,即__init__.py文件。
    如果没有__init__.py,则需要使用 .XXX进行文件引用

17. django.models.admin 
      Model.__str__()
      __str__() is a Python "magic method" that defines what should be returned if you call str() on the object. Django uses str(obj) (or the related function, unicode(obj) -- see below) in a number of places, most notably as the value displayed to render an object in the Django admin site and as the value inserted into a template when it displays an object. Thus, you should always return a nice, human-readable string for the object's __str__. Although this isn't required, it's strongly encouraged (see the description of __unicode__, below, before putting __str__ methods everywhere).
     Model.__unicode__()
The __unicode__() method is called whenever you call unicode() on an object. Since Django's database backends will return Unicode strings in your model's attributes, you would normally want to write a __unicode__() method for your model. The example in the previous section could be written more simply as:
If you define a __unicode__() method on your model and not a __str__() method, Django will automatically provide you with a __str__() that calls __unicode__() and then converts the result correctly to a UTF-8 encoded string object. This is recommended development practice: define only __unicode__() and let Django take care of the conversion to string objects when required.

18. CSV(Comma-Separated Values),文件以纯文本形式存储表格数据(数字和文本)。
      无需引入第三方库,可以用来做数据的存储。
      存在问题UnicodeDecodeError: 'gbk' codec can't decode byte 0x94 in position 48: illegal multibyte sequence。
      尝试解决,未果: 1) 文件头添加encoding; 2)打开文件时定义encoding

import csv

with open('filecsv.csv','r') as fp:
    freader = csv.reader(fp)
    rl = fp.readlines()
    for i in range(1,len(rl)):
        [ID,Action, Object, Method, Data, Memo] = map(lambda x: x.ljust(10),rl[i].split(","))
        print(ID,Action,Object,Method,Data,Memo)

19. 模块A定义一无返回值方法a(),在模块B中调用print(a()),输出a()结果和None。输出None原因是python的方法如果没有返回值,默认返回值为None

20. 模块T中方法a()的引用
      import T --> T.a()
      import T as t --> t.a()
      from T import* --> a()

21. 三目运算 ...?...:...
     python中的三目运算有两种方法可以实现
     1)result1 if condition else result2
     2)condition and result1 or result2  -- 有缺陷,具体看API中的FAQ 

22. list的反向输出
     1)使用循环,从len(list)-1 到 0 逐一输出,不改变原有list,[len(list)::-1]
     2)list.reverse(), 直接将list反转,改变原有list
     3)list[::-1],以步长为-1输出,不改变原有list

23. BIF: build in function, 内建函数,指python自身的内置函数

24. ZIP: zip(iter1 [,iter2 [...]]) --> zip object
     Return a zip object whose .__next__() method returns a tuple where the i-th element comes from the i-th iterable argument.The .__next__() method continues until the shortest iterable in the argument sequence is exhausted and then it raises StopIteration.
     解释:以元组形式返回迭代器的对应元素组合,直到最短长度的迭代器匹配完成。 例:

>>> a = [1,2,3,4]
>>> b = [6,7,8,9,0]
>>> c =zip(a,b)
>>> list(c)
[(1, 6), (2, 7), (3, 8), (4, 9)]

25.yield:generator生成器,生成一个迭代器iterator。在函数中使用yield,返回类型为generator,函数作为生成器,返回生成器参数构成的元组

>>> def test(m):
    a = b = 1
    while(a<m):
        yield a
        a,b=b,a+b        
>>> type(test(15))
<class 'generator'>
>>> test(15)
<generator object test at 0x00000000033D8F68>
>>> list(test(15))
[1, 1, 2, 3, 5, 8, 13]


yield a
 a,b=b,a+b  
 >>> type(test(15)) <class 'generator'> 
 >>> test(15) <generator object test at 0x00000000033D8F68>
 >>> list(test(15)) [1, 1, 2, 3, 5, 8, 13]


  修改程序
>>> def test(m):
    a = b = 1
    while(a<m):
        yield a,b
        a,b=b,a+b
>>> test(15)
<generator object test at 0x00000000033D8F68>
        yield a,b
        a,b=b,a+b
>>> test(15)
<generator object test at 0x00000000033D8F68>

>>> list(test(15))
[(1, 1), (1, 2), (2, 3), (3, 5), (5, 8), (8, 13), (13, 21)]

26. 偏函数 -- import functoolspartial(func, *args, **keywords) - new function with partial application of the given arguments and keywords. 

#通过partial实现一个新的函数,新函数需要给定指定的参数或关键字,即用指定的参数替代原有函数的参数

import functools

def test(a,b):
    print(a,"-",b)

test(1,2)

t = functools.partial(test,5)
t(6)

print(functools.partialmethod(t))

>>>>
1 - 2
5 - 6
functools.partialmethod(functools.partial(<function test at 0x000000000336E488>, 5), , )

27. from itertools import islice (迭代器切片)

>>> from itertools import islice
>>> a = '12345'
>>> list(islice(a,0,len(a)))
['1', '2', '3', '4', '5']

28. export CSV file

with open('csv_file_name','a(append model, store all)',newline='') as csvfile:
    spamwriter = csv.writer(csvfile)
    spamwriter.writerow([col1,col2......   ],)

29. 文件及方法引用

import 文件名 as 别名
      from 文件名 import 方法名 as 别名
      __import__(“文件名中有空格”)
      mytest = __import__(“文件名中有空格”)  # mytest 引用的有空格的文件的别名

30. 生成Python文档

# 指定目录下的python文件,ABC.py
>> python -m pydoc -w ABC
   wrote ABC.html

# 点击ABC.htm查看ABC.py中的 class、method、function描述

# 启动pydoc服务
>> python -m pydoc -p port#

31. 日期时间处理

from datetime import datetime
import time

# current date and time
time.ctime()   #  weekday month day HH:mm:ss Year

time.localtime() # time.struct_time(tm_year=XXXX, tm_mon=X, tm_mday=X, tm_hour=X, tm_min=X, tm_sec=X, tm_wday=X, tm_yday=X, tm_isdst=X)

datetime.today() #  datetime.datetime(year, month, day, hh, mm, ss, microsecond)

datetime.today().isocalendar() # (year, week, weekday)

# timestamp to date & time
time.strftime("%Y-%m-%d",time.localtime(os.stat(f).st_ctime)) # file f created timestamp: os.stat(f).st_ctime

time.time() # Return the current time in seconds since the Epoch(1970-01-01 00:00:00 UTC).
datetime.now() # Returns new datetime object representing current time local to tz.
datetime.now().strftime("%Y-%m-%d") # output as format

32. 使用python执行系统命令(batch, shell)

##### 1. os.system: Execute the command in a subshell.   

import os
os.system("ver")
>>> Microsoft Windows [版本 10.0.xxxxx.xxx]


##### 2. os.popen: popen(cmd, mode='r', buffering=-1)

 import os
os.popen("ver")
>>> <os._wrap_close object at 0x000001F979C7EB80>  

os.popen("ver").read()
>>> '\nMicrosoft Windows [版本 10.0.xxxxx.xxx]\n' 

##### 3. subprocess: A class for flexibly executing a command in a new process
         subprocess.Popen: Execute a child program in a new process.
         shell: If true, the command will be executed through the shell.

import subprocess
subprocess.Popen('ver',shell=True).stdout
>>> Microsoft Windows [版本 10.0.xxxxx.xxx]

32. open file

# 使用with open比单纯使用open的优势在于不必显示的close
with open(file_name, open_mode,encoding) as fp:
    fl = fp.readlines()    # 读入所有文件行
    for fi in fl:
        print(fi)          # 按行输出文件内容

# open_mode: r, rb, w
# encoding: encoding='utf-8', 解决读入编码异常 或 以rb读入时显示乱码

33. 固定宽度的字符串

### 0 格式化输出
a,b =1,2
print("Format output %s, %s! " %(a, b))  # Format output 1, 2! 

### 1
"%Ns" %str     # 设定str长度为N,不足左补齐空格;最小输出字符串str
"%-Ns" %str    # 设定str长度为N,不足右补齐空格;最小输出字符串str

str = '123456'
"%10s" %a      # '    123456'
"%-10s" %a     # '123456    '
"%2s" %a       # '123456'

### 2
str.ljust(N,replace_str)  # 设定str长度为N,不足左补齐replace_str
str.rjust(N,replace_str)  # 设定str长度为N,不足右补齐replace_str

str = '123456'
a.ljust(10,'0')  # '1234560000'
a.rjust(10,'0')  # '0000123456'

### 3
str.zfile(N)   # 设定str长度为N,不足左补齐0

str = '123456'
a.zfill(10)    # '0000123456'

### 4
"%0Nd" %d    # 设定数字长度为N,不足左补齐0; 默认补齐空格,可选项为 0

d = 99
"%010d" %b   # '0000000045'

34. 文件及文件夹

import glob
glob.glob("./*.*") # Return a list of paths matching a pathname pattern. 
glob.glob("C:\Windows\System32\*.*")  # show all files in path C:\Windows\System32\ 

import os
os.path.isdir() # Return true if the pathname refers to an existing directory.
os.path.isdir("C:\Windows\System32") # True
os.path.isdir("C:\Windows\HelpPane.exe") # False

os.path.isfile(path) # Test whether a path is a regular file
os.path.isfile("C:\Windows\HelpPane.exe") # True
os.path.isdir("C:\Windows") # False

os.path.split() # Return tuple (head, tail) where tail is everything after the final slash
os.path.split("C:\Windows\System32\HelpPane.exe") # ('C:\\Windows\\System32', 'HelpPane.exe')

os.path.splitext(p) # Split the extension from a pathname.
os.path.split("C:\Windows\System32\HelpPane.exe") # ('C:\\Windows\\System32\\HelpPane', '.exe')

35. 线程
线程,thread,操作系统能够进行运算调度的最小单位。进程,Process,程序一次运行活动,系统资源分配和调度的基本单位。
进程是操作系统分配资源的单位,线程是调度的基本单位,线程之间共享进程资源。一个进程可以包含多条线程,一条线程只归属一个进程。

import threading

def run_thread(args):
    for i in range(5):
        print(args,i)

thread_1 = threading.Thread(target=run_thread, args=("Thread 1 is run. ",))
thread_2 = threading.Thread(target=run_thread, args=("Thread 2 is run. ",))

thread_1.start()      # run thread 1
thread_2.start()      # run thread 2

run_thread("This order 3. ")     # run order 3
run_thread("This order 4. ")     # run order 4

>>>>>>>>>
Thread 1 is run. Thread 2 is run. This order 3.    000
Thread 1 is run. Thread 2 is run. This order 3.    111
Thread 1 is run. Thread 2 is run. This order 3.    222
Thread 1 is run. Thread 2 is run. This order 3.    333
Thread 1 is run. Thread 2 is run. This order 3.    444

This order 4.  0
This order 4.  1
This order 4.  2
This order 4.  3
This order 4.  4

36. 排充,Sort

###### 列表排序, list sort ######
lt = [5,3,1,2,4,6]
lt.sort()     #升序/正序
print(lt)    

lt.sort(reverse=True)   #降序/逆序
print(lt)

>>>
[1, 2, 3, 4, 5, 6]  #升序/正序
[6, 5, 4, 3, 2, 1]  #降序/逆序


###### 字典排序, dict sort ######
import operator

dic = {5:2,3:4,1:6,2:5,4:3,6:1}
# 字典按key排序
print(dict(sorted(dic.items(),key=operator.itemgetter(0))))   #升序/正序
print(dict(sorted(dic.items(),key=operator.itemgetter(0),reverse=True)))  #降序/逆序

# 字典按value排序
print(dict(sorted(dic.items(),key=operator.itemgetter(1))))   #升序/正序
print(dict(sorted(dic.items(),key=operator.itemgetter(1),reverse=True)))  #降序/逆序

>>> 
{1: 6, 2: 5, 3: 4, 4: 3, 5: 2, 6: 1}  #key 升序/正序
{6: 1, 5: 2, 4: 3, 3: 4, 2: 5, 1: 6}  #key 降序/逆序
{6: 1, 5: 2, 4: 3, 3: 4, 2: 5, 1: 6}  #value 升序/正序 
{1: 6, 2: 5, 3: 4, 4: 3, 5: 2, 6: 1}  #value 降序/逆序

37. django.db.utils.OperationalError: no such table XXX
     1)确认表是否存在
     2)重新执行表迁移命令: migrate / makemigrations
38. eval()
    Evaluate the given source in the context,计算所给内容,内容必须是字符串

>>> eval('1+1')
2

>>> eval("'*'*5")
'*****'

>>> eval('0x11')   # 16进制转10进制
17

>>> eval('0o11')   # 8进制转10进制
9