Python学习小技巧
Python中很多小技巧,可以提高代码精简程度。并且可以看懂大神写的高级的Python代码。
本文以Python语言及其应用(人民邮电出版社2016年版,Bill Lubanovic)为学习手册记录的一些小方法。
生成器
yield 注意其与return在使用顺序上也有不同
def my_range(first=0,last=10,step=1)
number=1
while number<last
yield number
number += step
如果使用return的顺序,则输出可能有问题
装饰器
@document_it
def add_int(a,b)
相当于在document_it 中调用add_int,因而是对add_int的一种装饰,按照document_it这种更复杂更贴合徐需求的方式来调用。
多个装饰器先执行后面的(即与函数更近的那一个)
编写自己的异常
class UppercaseException(Exception):
pass
if ...:
raise UppercaseException(word)
Python的异常就是普通的程序流程,而不是程序错误
自己定义异常,可以在结构控制中更加灵活的控制流程
标准库的一些东西
setdefault() 给字典赋默认值,如果已经有值则不改变原有值。若建不存在则添加这项。
defaultdict(int) , 利用函数返回值(包括lambda)为新键指定默认值。int(),list(),dict()或者空参时为None
否则建立不带自动初始化的字典,新增元素需要手动初始化
from collections import Counter 计数器
Counter(alist) 或者 Counter,most_common(x)返回大于x的降序的统计
不同计数器可组合加减等运算
有序字典OrdereDict()
双端队列deque,可以popleft()和pop()
继承
子类通过super从父类中获得帮助 super().**
对属性的访问
使用双下划线保证外部无法访问私有属性(Python自动给双下划线改了名字)
class Duck():
def __init__(self, input_name):
self.__name = input_name
@property #用于指示getter方法
def name(self):
print('inside the getter')
return self.__name
@name.setter #用于指示setter方法
def name(self,input_name):
print('insede the setter')
self.__name = input_name
方法的类型
以self为第一个参数的叫实例方法instance method
与之相对,类方法@classmethod作用于整个类,第一个参数为类本身,写作cls
(有点静态函数那种意思)
静态方法 @staticmethod 甚至可以不用声明就可以用
上一本书找不到了,下面换成《Python学习手册》第四版,李军、刘红伟 译
本书可从我的CSDN上下载
https://blog.csdn.net/u012925946
字典
有可变性,靠键来映射,Python核心对象集合中唯一的一种映射类型。
重访嵌套:
a_dic = { 'name':{'first':'Bob' , 'last':'Smith'} , 'age':50,‘job’:['jan' , 'dev'] }
可以通过a_dic[‘name’][‘first’]来访问到Bob
字典中job列表是独立的内存,可以a_dic[‘job’].append(‘worler’)
使用列表的方法来增加内存。
键的排序:循环与迭代
for while 和 列表解析表达式 都是通用迭代工具,遵守迭代协议的任意对象(表示内存中物理存储的序列,或者每次产生一个元素的对象)。可迭代对象可以用next返回后续的东西,因而不需要for来得到一个序列再操作。
列表解析式和相关函数如map、 filter一般比for快(也许是两倍)
squares = [x**2 for x in [1,2,3,4,5] ],返回[1,4,9,16,25]
可能不存在的键
D= {'a':5 , 'b':6 , 'c':7}
val = D.get('x' , 0) #不存在则赋值0
#即
val = D['x'] if 'x' in D else 0
动态类型
a=3时自动确定a是整型,无需提前声明
变量、对象和引用
变量永远不会有任何和它关联的类型信息或约束。
类型的概念只存在于对象中。
变量出现在表达式中,会马上被当前的引用的对象所替代,无论这个对象是什么类型。
必须在引用前赋值。(赋值时就是变量创建的时刻)
a=3
1,创建一个对象代表值3
2,创建一个变量a,如果还没有创建过的话
3,将变量与对象3相连接
每个对象包含2个头部信息,1个头部信息标记了这个对象的类型;另一个是引用的计数器(用来决定是否回收这个对象)
对象的垃圾回收:引用的计数器=0时
exampe:
a=3
b=a
则a,b两个变量都指向同一个整型对象3
a=a+2
此时,对b没有影响,无法改变对象3的值,因为整数是不可变的,没法在原处修改。
共享引用和在原处修改
list1 = [2,3,4]
list2 = list1
在列表中的元素是通过位置读取的,list1[0]引用对象2,是第一个元素。
list1[0]=24则会影响list2[0]
但是,两个list也是对象,如果list1 = 25 , 则不会影响list2
可变对象:列表、字典、一些通过class定义的对象
共享引用和相等
L = [1,2,3]
M = L
M == L # same value , True
L is M #same object , True,检查对象同一性
小的整数和小字符串有时,没有引用时并不会立刻删除,而是在缓存中等待再次被声明
L = [1,2,3]
M = [1,2,3]
M is L # False 只是值相等,并不是同一个对象
X = 42
Y = 42
X == Y # True
X is Y # True,本来不应该是同一个对象,
#但是,由于缓存导致两个变量指向同一个对象
这也是Python对速度的优化,sys.getrefcount(1)是837,说明对1引用了800多次,问题不大,反正整型1也不会被修改
因而,复杂情况下,追踪变量名的框图意义不大,因为可能会改变
动态类型也是Python中的多态的根本
numpy的使用小技巧
numpy.frombuffer(buffer, dtype=float, count=-1, offset=0)
输入一个缓冲实例,类别,数量,开始读取的位置
得到np.ndarray类型的返回值
打印数组
np.set_printoptions(threshold=nan)
本来长列表,会自动简略打印一部分。想打印全必须用这个设置
用了设置,打印某些列表就会报错:
‘<’ not supported between instances of ‘int’ and ‘str’
一些社区建议更换使用
np.set_printoptions(threshold=sys.maxsize)
就不会出现这个问题