写python代码时,经常会遇到一些问题,这边做个小结备份。
未完待续…
1、参数中* 和**的用法
python函数中经常看到*args 和 **kwargs,但是实际用法在于*和**,args只是类似于变量名。
*args:允许传递任意数量(>=0)的参数给python函数,以tuple类型显示。
**kwargs:允许传递任意数量(>=0)的key-value格式的参数,以dict类型显示。
直接甩代码更清晰:
>>> def testForArgs(arg0, *arg1, **arg2):
... print(arg0, arg1, arg2)
...
#参数只有一个时
>>> testForArgs(1)
1 () {}
#多个参数情况
>>> testForArgs(1,2,3,4)
1 (2, 3, 4) {}
>>> testForArgs(1,2,3,4, key1='Mary', key2='Haha')
1 (2, 3, 4) {'key1': 'Mary', 'key2': 'Haha'}
>>> testForArgs(key1='Mary')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: testForArgs() missing 1 required positional argument: 'arg0'
2、什么是函数签名?使用装饰器后如何保持函数签名?
定义:一个函数由这么几部分组成,函数名、参数个数、参数类型、返回值。
函数签名由参数个数与其类型组成。
函数在重载时,利用函数签名的不同(即参数个数与类型的不同)来区别调用者到底调用的是那个方法。
甩代码:
# -*- coding: utf-8 -*-
import functools
#写一个函数装饰器,来缓存函数的值
def cache(func):
cache_dict = {}
# @functools.wraps(func)
def wrapper(*args, **kwargs):
key = repr(*args, **kwargs)
if key in cache_dict:
return cache_dict[key]
else:
#使用cache_dict缓存同一个sql的结果
cache_dict[key] = func(*args, **kwargs)
return cache_dict[key]
wrapper.csrf_exempt = True
functools.update_wrapper(wrapper, func)
return wrapper
@cache
def execute_query(sql):
print('hit db')
return 'result'
#函数名是否发生变化,保持函数签名
print(execute_query)
# <function execute_query at 0xb709c89c>
print(execute_query('select * from table1'))
# hit db
# result
#缓存过的key不再缓存
print(execute_query('select * from table1'))
# result
print(execute_query('select * from table2'))
# hit db
# result
保持函数签名,使用的是functools中的wraps和update_wrapper方法,具体调用代码可以看出来。
如果不调用functools方法的话,很明显print(execute_query)的方法名就变成wrapper了。
3、python多重继承时,继承哪一层父方法?
python继承顺序遵循C3算法,根据拓扑排序,只要在一个地方找到了所需的内容,就不再继续查找。
具体看这个链接:
https://kevinguo.me/2018/01/19/python-topological-sorting/
参考链接:
https://stackoverflow.com/questions/3394835/args-and-kwargs
https://www.the5fire.com/functools-update-wrapper.html