传递元组
用法1:a, b = <some expression>
具有两个值的一个元组,使用一个元组可满足一个函数返回两个不同的值
>>> def get_error_details():
... return (2, 'details')
...
>>> errnum, errstr = get_error_details()
>>> errnum
2
>>> errstr
'details'
用法2:Python 中交换两个变量的最快方法
>>> a = 5; b = 8
>>> a, b
(5, 8)
>>> a, b = b, a
>>> a, b
(8, 5)
特殊方法
用来模拟内置类型的某些行为
下面的表格列出了一些有用的特殊方法。
- __init__(self, ...)
这一方法在新创建的对象被返回准备使用时被调用。
- __del__(self)
这一方法在对象被删除之前调用(它的使用时机不可预测,所以避免使用它)
- __str__(self)
当我们使用 print 函数时,或 str() 被使用时就会被调用。
- __lt__(self, other)
当小于运算符(<)被使用时被调用。类似地,使用其它所有运算符(+、> 等等)时都会有特殊方法被调用。
- __getitem__(self, key)
使用 x[key] 索引操作时会被调用。
- __len__(self)
当针对序列对象使用内置 len() 函数时会被调用
assert 语句
如果不为真,则将抛出AssertionError
assert len(mylist) >= 1
装饰器
创建了一个 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")