在对另一个问题的答案的评论中,有人说他们不确定functools.wraps在做什么.所以,我问这个问题,以便在StackOverflow上有一个记录,供将来参考:究竟functools.wraps做了什么?
"Python装饰器"和"装饰器模式"之间有什么区别?
我应该何时使用Python装饰器,何时应该使用装饰器模式?
我正在寻找Python装饰器的例子和完成相同的装饰器模式.
@AcceptedAnswer
我知道Jakob Bowyer的回答是有效的.然而,Strikar的答案让我理解了原因.
在Srikar回答并研究了资源之后我写了这个例子,所以我可以想象和理解Python装饰器和装饰器模式.
我必须不同意 Strikar的" Python装饰器不是装饰器模式的实现 ".在我学到的东西之后,我坚信Python装饰器是装饰器模式的实现.只是不是经典的方式.
另外,我需要补充的是,尽管Strikar说" Python装饰器在定义时为函数和方法添加功能 ",但您可以在运行时轻松使用Python装饰器.
然而,我仍然认为Stiker的答案是被接受的,因为它帮助我理解了 Python中装饰器模式的实现.
"""
Testing Python decorators against the decorator pattern
"""
def function(string):
return string
def decorator(wrapped):
def wrap(string):
# Assume that this is something useful
return wrapped(string.upper())
return wrap
def method_decorator(wrapped):
def wrap(instance, string):
# Assume that this is something useful
return wrapped(instance, string.upper())
return wrap
@decorator
def decorated_function(string):
print('! '.join(string.split(' ')))
class Class(object): …Run Code Online (Sandbox Code Playgroud) 我正在尝试将可选参数传递给python中的类装饰器.在我目前的代码下面:
class Cache(object):
def __init__(self, function, max_hits=10, timeout=5):
self.function = function
self.max_hits = max_hits
self.timeout = timeout
self.cache = {}
def __call__(self, *args):
# Here the code returning the correct thing.
@Cache
def double(x):
return x * 2
@Cache(max_hits=100, timeout=50)
def double(x):
return x * 2
Run Code Online (Sandbox Code Playgroud)
第二个带有参数的装饰器覆盖默认的(max_hits=10, timeout=5在我的__init__函数中),不起作用,我得到了异常TypeError: __init__() takes at least 2 arguments (3 given).我尝试了许多解决方案,并阅读了有关它的文章,但在这里我仍然无法使它工作.
有什么想法解决这个问题?谢谢!
作为一个学习练习,我正在尝试实现一个类,它将模拟python的complex内置行为,但具有不同的行为__str__和__repr__方法:我希望它们以格式打印...
(1.0,2.0)
Run Code Online (Sandbox Code Playgroud)
...代替:
(1+2j)
Run Code Online (Sandbox Code Playgroud)
我第一次尝试只是从继承complex和重新定义__str__和__repr__,但存在的问题是,当非覆盖的方法被调用,一个标准的complex返回,并以标准格式打印:
>>> a = ComplexWrapper(1.0,1.0)
>>> a
(1.0,1.0)
>>> b = ComplexWrapper(2.0,3.0)
>>> b
(2.0,3.0)
>>> a + b
(3+4j)
Run Code Online (Sandbox Code Playgroud)
当所需的输出是(3.0,4.0).
我正在阅读有关元类的内容,并认为它们可以解决我的问题.从Python Class Decorator中的答案开始,我当前的实现如下:
def complex_str(z):
return '(' + str(z.real) + ',' + str(z.imag) + ')'
def complex_repr(z):
return '(' + repr(z.real) + ',' + repr(z.imag) + ')'
class CmplxMeta(type):
def __new__(cls, name, bases, attrs):
attrs['__str__'] = complex_str …Run Code Online (Sandbox Code Playgroud) 我想将模型字段显示help_text为title表单中的HTML 属性,而不是将其作为默认值附加到行的末尾.
我喜欢模型字段在一个地方(在模型定义本身中)的所有信息,因此不想title为每个小部件指定自定义.但是,如果有一种方法可以指定每个小部件的title属性应该等于的值,那就没关系help_text.那可能吗?我正在寻找一些效果:
widgets = {'url':TextInput(attrs={'title': help_text})}
Run Code Online (Sandbox Code Playgroud)
我能想到的另一种方法是为内置的Widget类型中的每一个创建自定义小部件.是否有更简单,更懒惰的方式来达到同样的效果?
使用Javascript也是一种选择,但这实际上只是一个非常遥远的最后手段.我认为这必须是一个相当普遍的用例; 你们过去怎么处理它?
我有无数来自 SQLAlchemy 的各种项目的 Python 类(还有一些来自 Pygame 的项目),我最近注意到其中许多项目中的一个模式:它们的构造函数总是这样:
class Foo(Base):
def __init__(self, first, last, email, mi=""):
self.first = first
self.last = last
self.email = email
self.mi = mi
Run Code Online (Sandbox Code Playgroud)
...由此构造函数所做的唯一一件事就是将一组位置参数传输到一组完全相同命名的数据成员中,不执行任何计算或其他函数调用。
在我看来,这种重复是不必要的,并且在更改时容易出现人为错误。
这让我想到了一个问题:是否可以自动生成这样的__init__(self, ...)函数,最好不要乱用 CPython 字节码或使用模板/宏来改变源文件本身?
我有一个抽象的基类,它以numpy数组的形式托管数据,知道如何处理这些数据,哪些可以解释matplotlib如何绘制它.为了容纳不同类型的数据,它有许多子类,如下所示:
class PlotData():
"""Base Class"""
subclasslist = []
@classmethod
def register(cls):
super().subclasslist.append(cls)
def __new__(self, initdata, *args, **kwargs):
for subclass in subclasslist:
try:
subclass.__test__(initdata)
except AssertionError:
continue
else:
break
else:
raise TypeError("Initdata does not fit any known subclass")
return subclass(initdata, *args, **kwargs)
class Plot3D(PlotData):
"""Subclass for 3d-plotting data"""
def __test__(initdata):
assert Data_is_the_right_kind
class Plot_XY(PlotData):
"""Subclass for for plotting X-Y relations of data"""
def __test__(initdata):
assert Data_is_the_right_kind
Run Code Online (Sandbox Code Playgroud)
现在,问题是如何将类引用引入子类列表.起初我想在类体中调用super().register(),但我无法获得对类本身的引用,这就是我想要存储在列表中的内容.一个小小的搜索已经产生了两种可能的解决方案,我想知道最好的解决方案是什么.
在每个类定义后添加一个调用,如下所示:
class Plot_XY(PlotData):
"""Subclass for for plotting X-Y relations of data""" …Run Code Online (Sandbox Code Playgroud) 在Python中是否有合理的方法来实现类似于Ruby中的mixin行为 - 也就是说,不使用继承?
class Mixin(object):
def b(self): print "b()"
def c(self): print "c()"
class Foo(object):
# Somehow mix in the behavior of the Mixin class,
# so that all of the methods below will run and
# the issubclass() test will be False.
def a(self): print "a()"
f = Foo()
f.a()
f.b()
f.c()
print issubclass(Foo, Mixin)
Run Code Online (Sandbox Code Playgroud)
我有一个模糊的想法,与类装饰师这样做,但我的尝试导致混乱.我对该主题的大多数搜索都指向了使用继承(或者在更复杂的场景中,多重继承)来实现mixin行为.
我希望通过让每个子类在父类保存的列表中注册自己来创建给定类的所有子类的列表,即类似这样的事情:
class Monster(object):
monsters = list()
class Lochness(Monster):
Monster.monsters.append(Lochness)
class Yeti(Monster):
Monster.monsters.append(Yeti)
Run Code Online (Sandbox Code Playgroud)
这显然不起作用,因为当我想将它们添加到列表中时尚未创建类.而且,如果它是自动完成的话会更好(比如__subclass__)
我知道__subclass__有这个功能,但我想知道(我自己的启发)你自己如何实现它.
看起来你想创建一些类元类的子类,它创建了一些用Monster注册它的东西?或者完全偏离基础
我是Python的新手,我不明白函数本身看起来有什么属性.在下面的代码中,有一个名为f的函数,稍后在代码中引用了名为f.count的函数.一个函数,即f,如何有一个.count?我收到一条错误消息:'NoneType'对象在该行上没有属性'count',所以它显然还没有该属性.我该如何赋予它属性?
def fcount(n):
print n.__name__
@fcount
def f(n):
return n+2
for n in range(5):
print n
#print f(n)
print 'f count =',f.count #THE LINE CAUSING THE ERROR MENTIONED ABOVE
@fcount
def g(n):
return n*n
print 'g count =',g.count
print g(3)
print 'g count =',g.count
Run Code Online (Sandbox Code Playgroud)
编辑:添加了fcount(),它没有做任何事情,还有关于错误的详细信息.
python ×9
decorator ×4
arguments ×1
attributes ×1
constructor ×1
data-members ×1
django ×1
forms ×1
function ×1
functools ×1
inheritance ×1
metaclass ×1
mixins ×1
models ×1
ruby ×1