python小知识点
传递元组
一个函数中返回两个不同的值
-
案例:
>>> def get_error_details(): return (2,"details"); >>> >>> errnum,errstr = get_error_details(); >>> errnum 2 >>> errstr 'details' >>>
-
注意
-
a,b=<some expression>的用法会将表达式的结果解释为具有两个值的一个元组。这也意味着在Python中交换两个变量的最快方法是:
>>> a=5;b=9; >>> a,b (5, 9) >>> a,b=b >>> a,b=b,a >>> a,b (9, 5) >>>
-
特殊方法
- 诸如init和del等一些方法对于类来说有特殊意义;特殊方法用来模拟内置类的某些行为
- 如果你想了解所有的特殊方法,请参阅手册
单语句块
-
案例:
>>> flag = True; >>> if flag:print('Yes'); Yes >>>
单个语句是原地立即使用的,它不会被看作是一个单独的块。
Lambda表格
lambda语句可以创建一个新的函数对象。从本质上说,lambda需要一个参数,后跟一个表达式作为函数体,这一表达式执行的值将作为这个新函数的返回值
-
案例:
points = [{'x':2,'y':3}, {'x':4,'y':1}]; points.sort(key=lambda i: i['y']); print(points); C:\Users\Administrator\Desktop>python hello.py [{'x': 4, 'y': 1}, {'x': 2, 'y': 3}]
- 要注意到一个list的sort方法可以获得一个key参数,用以决定列表的排序方式。在我们的案例中,我们希望进行一次自定义排序,为此我们需要编写一个函数,但是又不是为函数编写一个独立的def块,只在这一个地方使用,因此我们使用Lambda表达式来创建一个新函数
列表推导
列表推导(List Comprehension)用于从一份现有的列表中得到一份新列表
-
案例:
listone=[2,3,4]; listtwo=[2*i for i in listone if i>2]; print(listtwo); C:\Users\Administrator\Desktop>python hello.py [6, 8]
当满足了某些条件时(if i>2),我们进行指定的操作(2*i),以此来获得一份新的列表。要注意到原始列表依旧保持不变
在函数中接受元组与字典
有一种特殊方法,即分别用*或**作为元组或字典的前缀,来使它们作为一个参数为函数所接收。当函数需要一个可变数量的实参时,这将颇为有用
-
案例:
>>> def powersum(power,*argv): total = 0; for i in argv: total += pow(i,power); return total; >>> powersum(2,3,4) 25
- 因为我们在args变量前添加了一个*前缀,函数的所有额外参数都将传递到argv中,并作为一个元组予以存储
assert语句
assert语句用以断言某事是真的。如果其不是真的,就抛出一个错误
-
案例:
>>> mylist=['ab','ff']; >>> assert len(mylist)>=2; >>> mylist.pop(); 'ff' >>> assert len(mylist)>=2 Traceback (most recent call last): File "<pyshell#30>", line 1, in <module> assert len(mylist)>=2 AssertionError >>>
装饰器
装饰器(Decorators)是应用包装函数的快捷方式。这有助于将某一功能与一些代码一遍又一遍地“包装”
举个例子,我为自己创建了一个retry装饰器,这样我可以将其运用到任何函数之中,如果在一次运行中抛出了任何错误,它就会尝试重新运行,直到最大次数5次,并且每次运行期间都会有一定的延迟。这对于你在对一台远程计算机执行网络调用的情况十分有用:
-
案例:
from time import sleep from functools import wraps import logging logging.basicConfig() log = logging.getLogger("retry") def retry(f): @wraps(f) def wrapped_f(*args,**kwargs): MAX_ATTEMPTS = 5; for attempt in range(1,MAX_ATTEMPTS+1): try: return f(*args,**kwargs); except: log.exception("Attempt %s/%s failed: %s", attempt,MAX_ATTEMPTS, (args,kwargs)); sleep(10*attempt); log.critical("All %s attempts failed : %s", MAX_ATTEMPTS,(args,kwargs)); return wrapped_f; counter = 0; @retry def save_to_database(arg): print("Write to a database or make a network call or etc."); print("This will be automatically retried if exception is thrown"); global counter; counter+=1; #这将在第一次调用时抛出异常 #在第二次运行时将正常工作 if counter<2: raise ValueError(arg); if __name__=="__main__": save_to_database("Some bad value"); C:\Users\Administrator\Desktop>python hello.py powersum(2,3,4) Write to a database or make a network call or etc. This will be automatically retried if exception is thrown ERROR:retry:Attempt 1/5 failed: (('Some bad value',), {}) Traceback (most recent call last): File "hello.py", line 12, in wrapped_f return f(*args,**kwargs); File "hello.py", line 31, in save_to_database raise ValueError(arg); ValueError: Some bad value Write to a database or make a network call or etc. This will be automatically retried if exception is thrown