gpt4 book ai didi

python - 在类 "major flaw"中实现装饰器?

转载 作者:太空宇宙 更新时间:2023-11-03 13:28:35 25 4
gpt4 key购买 nike

为什么这个装饰器策略被认为是不好的? (..或者是!?)

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)

这行得通。但是,根据下面的资源,这是不好的做法。原因是:

[...] there is major flaw in this approach: atomic_rating_change becomes an instance method of the User class. That doesn’t make any sense. More than this, it doesn’t even work as a method: if you call it, the decorated parameter will be used as self.

https://medium.com/@vadimpushtaev/decorator-inside-python-class-1e74d23107f6

我不明白为什么 atomic_rate_change 是一个实例方法是个问题/错误/不好。我只打算在类里面使用装饰器。也许在这种情况下没关系?

最佳答案

在风格上,将不是方法的函数定义放入类定义中有点不合适(恕我直言,它甚至可以是非 pythonic 的)。 Flat is better than nested , 所以最好在类之外声明函数。这样,当读者查看您的类(class)时,就不会混淆为什么有一个不采用 self方法。作为参数(因为当函数只是一个装饰器时,它被声明为一个方法,尽管如果函数是 @staticmethod 则略有不同)。

如果您担心它会在类外使用,请在它前面加上 _ 前缀然后 from my_package import *不会导入它。它仍然可以在该模块中使用,但除非明确导入,否则不会在外部使用。

实际上,作者指的是作用域偶尔出现的奇怪行为(类似于 Javascript 中关于是否使用 function() { ...() => { ... 的辩论,基于事物的作用域是如何确定的。)如果你不小心和不小心逻辑涉及 self在装饰器的错误部分,您可能会遇到范围问题。

我能看到在类内部使用函数的唯一优点可能是因为它更接近方法(但这引入了不必要的嵌套、潜在的作用域问题以及意识到这是装饰器而不是方法的认知负担),如果函数的名称以 _ 开头,则更好地隐藏该函数或 __ .

TL;DR 风格/Pythonicity 问题,以及潜在的范围问题。

关于python - 在类 "major flaw"中实现装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51155928/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com