第16篇,Python的其它知识

传递元组

如下

# 传递元组
def get_error_details():
    return (2,'details')

errnum,errstr = get_error_details()
print(errnum)
print(errstr)

# 快速交换两个变量
errstr,errnum = errnum,errstr
print(errnum)
print(errstr)

控制台

2
details
details
2

Process finished with exit code 0

a,b = 将表达式解释为具有两个值的一个元组。
快速交换两个变量的方法如上。

特殊方法

更所的特殊方法,请参考这里

# 特殊方法 举例说明

# __init__(self,...) 这一方法在新创建的对象被返回准备调用时被调用
# __del__(self) 这一方法在对象被删除之前调用(但是它的使用实际不可预测,所以避免使用)
# __str__(self) 当我们使用print函数时,或者str()被使用时就会被调用
# __it__(self,other) 当小于运算符(<)被使用时被调用。类似,使用其它所有运算符时都会有特殊方法被调用
# __getitem__(self,key) 使用x[key]索引操作时被调用
# __len__(self) 当针对序列对象使用内置len()函数时被调用
单语句块

我们已经见过每一个语句块都由其自身的缩进级别与其它部分相区分。但是如果语句块只包括单独的一行语句,那么我们可以在同一行指定它,比如条件语句和循环语句。
如下

flag = True
if flag: print('YES')

单个语句是在原地立即使用的,它不会被看做一个单独的块。

Lambda表格

lambda语句可以创建一个新的函数对象。从本质上说,lambda需要一个参数,后跟一个表达式作为函数体,这个表达式执行的值将作为这个新函数的返回值。
如下

# lambda表达式
point = [
    {'x':2,'y':3},
    {'x':4,'y':7}
]
point.sort(key=lambda i:i['x'])
print(point)
print("****************")
z = lambda x,y,z:x*y*z
print(z(999,95,82))

控制台输出

[{'x': 2, 'y': 3}, {'x': 4, 'y': 7}]
****************
77892210

Process finished with exit code 0

当我们需要编写一个函数,又不想为函数编写一个独立的def块时,就可以使用lambda表达式。

列表推导

列表推导用于从现有的列表中得到一份新的列表。当我们循环处理列表中的元素,并将其存储在一个新的列中中时,列表推导可以省下很多代码。
如下

# 列表推导
# 从已有列表中国推导出一份新的列表
listone = [2,3,4,5,6]
listtwo = [2*i*i for i in  listone if i>3]
print(listtwo)

控制台

[32, 50, 72]

Process finished with exit code 0
在函数中接收元组与字典

如下

# 在函数中接收元组与字典
# 接收元组
def powerSum(poewr,*ele):
    total = 0
    for i in  ele:
        print(i)
        total += pow(i,poewr)
    return  total

# 接收字典
def getkeyvalue(p,**dic):
    for k in  dic.values():
        print(k*p)
    print(dic)

print(getkeyvalue(3,a=3,b=4))
print('=====================')
print(powerSum(10,5,9,11))

控制台

9
12
{'a': 3, 'b': 4}
None
=====================
5
9
11
29433974627

Process finished with exit code 0

如上,我们使用*作为元组的前缀,函数所有的其它额外参数都将传递到ele中,并作为一个元组进行存储。**作为字典的前缀,额外的参数将被视为字典的键值对进行存储,并且,在传递参数时必须采用key=value的形式。

assert语句

assert用来断言Assert某件事是真的,如果不是真的,就会抛出AssertionError错误。
如下

# assert 语句
text = input('Please input content:')
assert  len(text) > 5

控制台

Please input content:qwert
Traceback (most recent call last):
  File "/Users/a1/Desktop/Python/PythonProjectFiles/More.py", line 62, in 
    assert  len(text) > 5
AssertionError

Process finished with exit code 1

如上,我们断言输入字符串的长度会大于5,当我们输入字符串长度小于等于5时,就会抛出AssertionError
相比捕获异常 以及定位问题或向用户显示错误信息然后退出,断言的优势更为明显。

装饰器

装饰器是应用包装函数的快捷方式,这有助于将某一功能与一些代码一遍又一遍的“包装”。如下,创建一个retry装饰器

from time import  sleep
from  functools import wraps
import logging

logging.basicConfig()
log = logging.getLogger('retry')

def retry(f):
    @wraps(f)
    def wrapped_f(*tup,**dic):
        MAX_ATTEMPTS = 5
        for attempt in range(1,MAX_ATTEMPTS + 1):
            try:
                return  f(*tup,**dic)
            except:
                log.exception("Attemp %s%s failed:%s",
                               attempt,
                              MAX_ATTEMPTS,
                              (tup,dic))
                sleep(2 * attempt)
        log.critical("All %s attemp failed: %s",
                     MAX_ATTEMPTS,
                     (tup,dic))
    return  wrapped_f

counter = 0

@retry
def saveToDatabase(ele):
    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
    
    # 前3次调用时抛出异常  
    # 第四次运行时讲正常工作(重试)
    if counter < 4:
        raise  ValueError(ele)

if not __name__ == 'main':
    saveToDatabase('Some bad value')

控制台

ERROR:retry:Attemp 15 failed:(('Some bad value',), {})
Traceback (most recent call last):
  File "/Users/a1/Desktop/Python/PythonProjectFiles/Decorators.py", line 14, in wrapped_f
    return  f(*tup,**dic)
  File "/Users/a1/Desktop/Python/PythonProjectFiles/Decorators.py", line 37, in saveToDatabase
    raise  ValueError(ele)
ValueError: Some bad value
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.
ERROR:retry:Attemp 25 failed:(('Some bad value',), {})
Write to a database or make a network call or etc.
Traceback (most recent call last):
This will be automatically retried if exception is thrown.
  File "/Users/a1/Desktop/Python/PythonProjectFiles/Decorators.py", line 14, in wrapped_f
    return  f(*tup,**dic)
  File "/Users/a1/Desktop/Python/PythonProjectFiles/Decorators.py", line 37, in saveToDatabase
    raise  ValueError(ele)
ValueError: Some bad value
ERROR:retry:Attemp 35 failed:(('Some bad value',), {})
Write to a database or make a network call or etc.
Traceback (most recent call last):
This will be automatically retried if exception is thrown.
  File "/Users/a1/Desktop/Python/PythonProjectFiles/Decorators.py", line 14, in wrapped_f
    return  f(*tup,**dic)
  File "/Users/a1/Desktop/Python/PythonProjectFiles/Decorators.py", line 37, in saveToDatabase
    raise  ValueError(ele)
ValueError: Some bad value
Write to a database or make a network call or etc.
This will be automatically retried if exception is thrown.

Process finished with exit code 0

如上 retry装饰器,可以将它运行到任何函数中,如果在前三次运行中抛出任何错误,它将会尝试重新运行,直到最大运行次数5次,并且每次重新运行之间还会有一定时间的延迟。
关于装饰器,可以参考 one 和two

你可能感兴趣的:(第16篇,Python的其它知识)