@在python中是装饰器的意思,它的用法比较复杂。假设我们要增强函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
def timer(func):
def f(x, y=10):
before = time()
rv = func(x, y)
after = time()
print('time taken: ', after - before)
return rv
return f
@timer
def add(x, y=10):
return x + y
装饰器接受func作为参数,并返回装饰好之后的func。上例等价于:
f = timer(add)
f(x,y)
此外还有类装饰器,其一般签名如下:
def cls_decorator(cls: type[T]) -> type[T]:
在python 3.5以后,@是一个操作符,表示矩阵-向量乘法。
A@x就是矩阵-向量乘法np.dot(A, x)。
参见:
https://www.zhihu.com/question/26930016
如何理解Python装饰器?
https://mp.weixin.qq.com/s/1QjJqFfJNNych9b6ae5VUg
深入理解Python装饰器
https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208
使用@property
https://www.liaoxuefeng.com/wiki/1016959663602400/1017451662295584
装饰器
https://mp.weixin.qq.com/s/qMT46hjOQeXsjVpZPqLRVA
一文读懂Python装饰器
https://mp.weixin.qq.com/s/_ZvF6jK5Jo4rFGwHvEoAig
一文读懂Python装饰器由来
https://mp.weixin.qq.com/s/Wsk6H3Z6HwGPKTRNYc2cLw
一个已经存在10年,却被严重低估的库(decorator)
使用importlib动态导入库和类的示例:
m = importlib.import_module(library_name)
model_cls = getattr(m, class_name)
在一些语言中,在函数中可以(嵌套)定义另一个函数时,如果内部的函数引用了外部的函数的变量,则可能产生闭包。闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。
用比较容易懂的人话说,就是当某个函数被当成对象返回时,夹带了外部变量,就形成了一个闭包。
https://mp.weixin.qq.com/s/qYKNGqItnSXq0-Zq2kMCKA
聊一聊Python中的闭包
class A(object):
def foo(self, x):
print("executing foo(%s,%s)" % (self, x))
print('self:', self)
@classmethod
def class_foo(cls, x):
print("executing class_foo(%s,%s)" % (cls, x))
print('cls:', cls)
@staticmethod
def static_foo(x):
print("executing static_foo(%s)" % x)
@classmethod类似于C++中的static,无须实例化就可以调用。@staticmethod则是普通成员函数的简写。python一般用cls表示类,而用self表示类的实例。当然,这只是编程规范的约束,而非编译器约束,使用其他名字也是可以的。
参考:
https://www.cnblogs.com/elie/p/5876210.html
python中@classmethod @staticmethod区别
由于python是动态脚本语言,它的class的用法也非常灵活。你甚至无须事先定义类的成员变量,而只需要运行时添加即可。
示例:
class A():
pass
a=A()
a.name = "Job"
a.age = 10
class Displayer():
def display(self, message):
print(message)
class LoggerMixin():
def log(self, message, filename='logfile.txt'):
with open(filename, 'a') as fh:
fh.write(message)
def display(self, message):
super().display(message)
self.log(message)
class MySubClass(LoggerMixin, Displayer):
def log(self, message):
super().log(message, filename='subclasslog.txt')
subclass = MySubClass()
subclass.display("This string will be shown and logged in subclasslog.txt")
python支持多重继承和多继承,且有自己独特的特性。
MRO全称方法解析顺序(Method Resolution Order),在多重继承和多继承存在的时候,寻找属性及方法的顺序。
上例中,MySubClass继承了两个父类LoggerMixin和Displayer。
Mixin是一种设计模式,Mixin类不能单独存在,上例中的super().display(message),如果没有MySubClass提供的Displayer类,则无法执行。
这两个父类如果存在同名函数的话,将按照参数表从左到右的优先级顺序确定执行的函数。
PS:C++遇到这种情况则必须显式指定使用哪个父类的函数。
上例如果使用深度优先的算法,C重载了D的一个方法,会导致搜索不到C的重载,只会用到D。
上例C和D有同名方法,正常应该使用D的方法(D,B应为一个整体,B的优先级比C高),但是如果广度优先就会使用到C的方法。
python3的mro使用c3 linearization算法来解决上述问题。
https://www.cnblogs.com/Hellowshuo/p/16111678.html
c3 linearization详解
-v: 打印运行信息。
-u: stdout立即输出,无缓冲。
https://blog.csdn.net/qq_32907349/article/details/52190796
Python的进阶:copy()与deepcopy()区别
https://mp.weixin.qq.com/s/bgk375-KxF-is5dIgV_p4g
5张图彻底理解Python中的浅拷贝与深拷贝
six是一个专门用来兼容Python 2和Python 3的库。它解决了诸如urllib的部分方法不兼容,str和bytes类型不兼容等“知名”问题。2x3=6?这难道就是得名的原因?
代码:
https://bitbucket.org/gutworth/six
文档:
https://bitbucket.org/gutworth/six
https://www.linuxzen.com/qian-yi-dao-python-3.html
迁移到Python 3
https://www.zhihu.com/question/19698598
Python 2和Python 3有哪些主要区别?
https://mp.weixin.qq.com/s/Q3cqLuOZDSMOdAjVrCDrtQ
在Python 2.7即将停止支持时,我们为你准备了一份3.x迁移指南
https://mp.weixin.qq.com/s/J4bBvu9z3BNcwMSmmL5SMQ
Python 2大限来了!113天后自生自灭,官方不再维护更新
文件print:
Python2: print >>sys.stderr, "fatal error"
Python3: print("fatal error", file=sys.stderr)
dict切片:
Python2:
self._layers = net.blobs.keys()
self._layers = self._layers[1:] # TypeError: 'dict_keys' object is not subscriptable
Python3:
self._layers = list(net.blobs.keys())
self._layers = self._layers[1:]
检查某对象是否为字符串或Unicode对象:
Python2: isinstance(anobj, basestring)
Python3: isinstance(anobj, str)
1.range会直接生成一个list对象。
2.xrange则不会直接生成一个list,而是每次调用返回其中的一个值。
所以xrange做循环的性能比range好,尤其是返回很大的时候,尽量用xrange吧,除非你是要返回一个列表。
Python 3只有range,效果和Python 2的xrange相仿,且支持slicing。
参考:
http://www.cnblogs.com/zhangjing0502/archive/2012/05/16/2503880.html
Python的range和xrange
class QuantType(Enum):
FP16 = auto()
auto函数用于自动分配枚举成员的值。
>>>member = Color.RED
>>>member.name
'RED'
>>>member.value
1
>>>Color['RED']
1
Enum默认有name和value两个属性。
普通Iterator:
for item in enumerate(list):
print(item)
带index的Iterator:
for index, item in enumerate(list):
print(index, item)
for i in [1,2,3,4]:
if i > 2:
print(i)
else:
print(i, '我是else')
dataclasses是python3.7引入的标准库模块。
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
# 创建对象
point = Point(x=1.0, y=2.5)
@dataclass
class FCConfig:
min_k: int = 512
@dataclass
class BlockConfig:
fc_config: FCConfig = field(default_factory=FCConfig)
上例中展示了dataclass的基本用法,以及dataclass嵌套的情况下,如何使用默认值,而不是参数,初始化对象。
print('y是一个负数' if y < 0 else 'y是一个非负数')
时间数据上的格式处理,主要指strftime和strptime函数。其中前者可将时间数据转换成指定格式的字符串,而后者则将字符串转换成时间数据。
import time
a = "2013-10-10 23:40:00"
timeArray = time.strptime(a, "%Y-%m-%d %H:%M:%S")
otherStyleTime = time.strftime("%Y/%m/%d %H:%M:%S", timeArray)
日期方面也是类似的做法。
datetime(2002, 12, 4).isoweekday() == 3
datetime(2001, 12, 31).isocalendar() == (2002, 1, 1)#(year, week number, weekday)
从上面的例子还可以看出,isocalendar可以完美的处理跨年问题。
eval函数用来执行一个字符串表达式,并返回表达式的值。
示例:
eval('pow(2,2)')
粗看起来,eval函数在上面的例子中有些多此一举。然而如果字符串来自外部的话,就完全不同了。我们完全可以在任何地方嵌入python脚本。然后,只需要在用到的时候,找到并加载该字符串即可。
https://blog.csdn.net/It_way/article/details/44815141
python 命令行参数解析 argparse简单分析
pickle提供了一个简单的持久化功能。可以将对象以文件(后缀名一般为*.pkl)的形式存放在磁盘上。
参考:
https://blog.csdn.net/sinat_29552923/article/details/70833455
Python pickle模块学习
pickle的反序列化存在安全漏洞:
https://www.zhihu.com/question/1296528119
字节跳动大模型训练被实习生恶意注入破坏代码,涉事者已被辞退,攻击带来的影响有多大?
https://zhuanlan.zhihu.com/p/89132768
从零开始python反序列化攻击:pickle原理解析 & 不用reduce的RCE姿势
dill是pickle的威力加强版。
除了提供pickle的功能之外,还可浏览对象的源代码。
示例:
dill.source.getsource(func)

您的打赏,是对我的鼓励