sve*_*ema 3 python python-2.7 python-decorators
为什么这个装饰策略被认为是坏的?(..或者是它!?)
class User(object):
def __init__(self):
self.thing = 5
def __atomic_rate_change(fn):
def wrapper(self,*args,**kwargs):
print "start magic"
self.thing += 1
fn(self,*args,**kwargs)
print "end magic"
return wrapper
@__atomic_rate_change
def foo(self,add):
print self.__atomic_rate_change # <bound method User.__atomic_rate_change of <__main__.User object at 0x6ffffe1ef50>>
self.thing += add
print "normal call {0}".format(self.thing)
test = User()
test.foo(1)
Run Code Online (Sandbox Code Playgroud)
这有效.但是,根据下面的资源,这是不好的做法.理由是:
[...]这种方法存在一个主要缺陷:atomic_rating_change成为User类的实例方法.这没有任何意义.除此之外,它甚至不能作为一种方法:如果你调用它,装饰参数将被用作self.
https://medium.com/@vadimpushtaev/decorator-inside-python-class-1e74d23107f6
我不明白为什么atomic_rate_change是一个实例方法是一个问题/错误/错误.我只是打算在类中使用装饰器.也许在这种情况下它没关系?
在风格上,将函数定义放入不是方法的类定义中是不合适的(甚至可以是unpythonic).Flat优于嵌套,因此最好在类外部声明函数.这样当读者看到你的类时,就不会混淆为什么有一个方法不self
作为参数(因为当它只是一个装饰器时,函数被声明为方法,尽管这是如果函数是a @staticmethod
)稍有不同.
如果您担心它在课外使用,请在前面添加一个_
,然后from my_package import *
不会导入它.它仍然可以在该模块中使用,但除非明确导入,否则不会在室外使用.
实际上,作者指的是范围的偶然奇怪的行为(类似于Javascript中关于是否使用function() { ...
或() => { ...
基于事物如何作用的辩论.)如果你不小心并且不小心有逻辑涉及self
你的错误部分装饰师,你可能有范围问题.
我可以看到在类中使用函数的唯一优点可能是因为它更接近于方法(但是引入了不必要的嵌套,潜在的作用域问题,以及认识到装饰器而不是方法的认知负荷),以及更好的隐藏如果它的名称以_
或开头的函数__
.
TL; DR文体/ Pythonicity问题,以及潜在的范围问题.