一尘不染

函数如何访问自己的属性?

python

是否可以从函数范围内访问python函数对象属性?

例如让我们

def f():
    return SOMETHING

f._x = "foo"
f()           # -> "foo"

现在,如果要返回_x属性内容“ foo”,则必须是什么?如果有可能(简单)

谢谢

更新:

我也想做以下工作:

g = f
del f
g()          # -> "foo"

更新2:

声明不可能(如果是这种情况),以及为什么,比提供一种方法来伪造它更令人满意,例如使用不同于函数的对象


阅读 117

收藏
2020-12-20

共1个答案

一尘不染

使函数的默认参数之一成为对函数本身的引用。

def f(self):
    return self.x
f.func_defaults = (f,)

用法示例:

>>> f.x = 17
>>> b = f
>>> del f
>>> b()
17

说明

原始张贴者想要一种不需要全局名称查找的解决方案。简单的解决方案

def f():
    return f.x

f在每个调用上执行不符合要求的全局变量的查找。如果f被删除,则功能失败。更复杂的inspect建议以相同的方式失败。

我们想要执行 早期绑定 并将绑定的引用存储在对象本身内。从概念上讲,以下是我们在做什么:

def f(self=f):
    return self.x

在上面,self是局部变量,因此不执行全局查找。但是,我们无法按原样编写代码,因为f在尝试将默认值绑定到该代码时尚未定义self。相反,我们在f定义后设置默认值。

装饰器

这是一个简单的装饰器,可以为您完成此操作。请注意self,与方法不同,自变量必须排在最后,而方法排在self第一位。这也意味着,如果任何其他参数采用默认值,则必须提供默认值。

def self_reference(f):
    f.func_defaults = f.func_defaults[:-1] + (f,)
    return f

@self_reference
def foo(verb, adverb='swiftly', self=None):
    return '%s %s %s' % (self.subject, verb, adverb)

例:

>>> foo.subject = 'Fred'
>>> bar = foo
>>> del foo
>>> bar('runs')
'Fred runs swiftly'
2020-12-20