类属性在功能上依赖于其他类属性

时间:2018-04-17 15:43:21

标签: python class

我正在尝试使用静态类属性来定义另一个静态类属性,我认为可以通过以下代码实现:

f = lambda s: s[::-1]
class A:
    foo = "foo"
    bar = f(A.foo)

然而,这导致NameError: name 'A' is not defined。我找到了为什么 here的解释,但这并没有解释如何应该解决这个问题。那么如何定义A.bar == "oof"

3 个答案:

答案 0 :(得分:0)

由于您在课堂范围内呼叫f,只需传递foo

f = lambda s: s[::-1]
class A:
  foo = 'foo'
  bar = f(foo)

print(A.bar)

输出:

oof

答案 1 :(得分:0)

这样做的方法是:

class A:
    foo = "foo"
    bar = f(foo)

类定义很像函数体。它被评估一次以定义类,而不是每次调用函数时进行评估,但无论如何,您在该范围内本地定义的任何变量都可以在该范围内使用。

因此,foo是定义类的代码中的局部变量。令人困惑的是,对于在创建类之后运行的代码,局部变量不再存在,而foo是该类的属性:

class A:
    foo = "foo"
    bar = f(foo) # this works
    bar = f(A.foo) # this doesn't, because there is no A yet
    def spam(self):
        print(A.foo) # this works
        print(self.foo) # so does this
        print(type(self).foo) # and this
        print(foo) # this is an error, because the "local" foo no longer exists

答案 2 :(得分:0)

您通常无法在自己的定义中按名称引用类,因为它尚未创建。 (有时)解决这个限制的一种方法是使用所谓的类装饰器(参见PEP 3129),这是一个在的函数>它已创建。

我在good tutorial找到了关于他们以及他们如何运作的信息。

由于我们想要将参数传递给装饰器,因此需要一个额外的功能,它可以作为你可以称之为“装饰工厂”的工具。根据传递给它的参数,即时生成所需的类装饰器。

这就是我的意思:

def decorate(func, arg):
    def decorator(cls):
        setattr(cls, 'foo', arg)
        setattr(cls, 'bar', func(arg))
        return cls

    return decorator

f = lambda s: s[::-1]

@decorate(f, 'foo')
class A:
    pass

print(A.foo)  # -> foo
print(A.bar)  # -> oof

这是另一种使用Python的装饰器语法的方法,但是在某种意义上它用于修改通常已经成为方法的类属性的方式略有不同寻常的方式以这种方式,它的值将是使用给定的参数调用某个指定函数的结果:

def call(*argv, **kwargs):
    def call_fn(fn):
        return fn(*argv, **kwargs)
    return call_fn

f = lambda s: s[::-1]

class A:
    foo = 'foo'
    @call(f, foo)  # Makes bar become the result of calling f with the argument.
    def bar(func, arg):
        return func(arg)


print(A.foo)  # -> foo
print(A.bar)  # -> oof