【问题标题】:How are function attributes transparently viewed by a method方法如何透明地查看函数属性
【发布时间】: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


【解决方案1】:

方法对象实现__getattribute__ 将未知属性的属性访问委托给底层函数对象。但是,他们不委托__setattr__,这就是分配失败的原因。如果你想看代码,那就是method_getattro in Objects/classobject.c

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-23
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-13
    • 2012-12-04
    • 2021-01-20
    相关资源
    最近更新 更多