【发布时间】:2018-10-30 18:09:11
【问题描述】:
我最近写了一些需要标记属性的函数:
def fn1(): pass
fn1.mark = True
实际的标记是由装饰者完成的,但它既不是这里也不是那里。我担心的是,当我以相同的方式标记类中的方法时,绑定方法时标记将不可见:
class A:
def meth1(): pass
meth1.mark = True
但实际上属性是可见的就好了:
>>> fn1.mark
True
>>> A.meth1.mark
True
>>> A().meth1.mark
True
但是,属性不能在绑定方法中分配或删除,因为它可以在函数中:
>>> A().meth1.mark = False
AttributeError: 'method' object has no attribute 'mark'
>>> del A().meth1.mark
AttributeError: 'method' object has no attribute 'mark'
方法的属性如何在绑定时可见?
【问题讨论】:
-
对您的问题的疑问 - 函数/方法属性是否对 func/meth 本身有任何贡献?我尝试了
def fn2(): print("foo" if mark else "bar"),但是当分配fn2.mark = True; fn2()时,我收到了NameError(如预期的那样)。对象具有自身不可访问的属性似乎有点违反直觉?我了解您的属性只能有助于外部范围。例如[f() for f in funcs if f.mark] -
@Idlehands:属性和局部变量是完全不同的东西。只要您实际执行属性访问而不是变量查找,就可以在函数中访问属性:
print("foo" if fn2.mark else "bar"). -
这与实例属性和方法局部变量的情况相同,其中方法需要使用
self.whatever而不仅仅是whatever来访问属性。 -
谢谢@user2357112,这一切都清楚了。只是我的困惑!这非常简洁,并且可能提供更大的灵活性,谢谢你们。
-
@Idlehands。另一种思考方式是函数的代码存在于代码对象中,该代码对象可能被多个函数对象引用,因此引用其中一个对象的属性没有多大意义。你看不到这么多,但想象一个嵌套函数,就像装饰器经常返回的那样。首次引用函数时,代码对象会编译一次。但是每次调用装饰器时,都会创建一个新的函数对象,每次都可能具有不同的属性。所有这些函数都引用相同的代码。
标签: python methods attributes