类属性依赖于其他类属性

lg5*_*g53 4 python class-attributes

我想创建一个类属性,它依赖于另一个类属性(我告诉属性,而不是实例属性)。当此类属性是字符串时,如本主题所示,建议的解决方案

class A:
    foo = "foo"
    bar = foo[::-1]

print(A.bar)
Run Code Online (Sandbox Code Playgroud)

工作正常。但是,当类属性是列表或元组时,就像我的例子一样,以下代码不起作用......

x=tuple('nice cup of tea')

class A:
  remove = ('c','o','a',' ')
  remains = tuple(c for c in x if not c in remove)

print(A.remains)
Run Code Online (Sandbox Code Playgroud)

增加

Traceback (most recent call last):
  File "[***.py]", line 3, in <module>
    class A:
  File "[***.py]", line 5, in A
    remains = tuple(c for c in x if not c in remove)
  File "[***.py]", line 5, in <genexpr>
    remains = tuple(c for c in x if not c in remove)
NameError: name 'remove' is not defined
Run Code Online (Sandbox Code Playgroud)

如果我的类属性不太复杂(如简单字符串,如前面提到的主题),为什么这种方法可以工作,但对于元组却不起作用?

经过调查,我发现是这样的:

x=tuple('nice cup of tea')

def sub(a,b):
   return tuple(c for c in a if not c in b)

class A:
  remove = ('c','o','a',' ')
  remains = sub(x, remove)

print(A.remains)
Run Code Online (Sandbox Code Playgroud)

这有效,但不适合我,原因如下:

  • 我不明白为什么这个通过中介功能能够起作用,而不是没有。
  • 我不想只为带有基本操作的单行添加函数。

wja*_*rea 5

Python 试图在全局范围内查找remove,但那里不存在。x另一方面,在封闭(类)范围中查找。

请参阅文档:

名称解析

类定义块和exec()和的参数eval()在名称解析上下文中是特殊的。类定义是可以使用和定义名称的可执行语句。这些引用遵循名称解析的正常规则,但在全局命名空间中查找未绑定的局部变量除外。类定义的命名空间成为类的属性字典。类块中定义的名称范围仅限于该类块;它不扩展到方法的代码块——这包括推导式和生成器表达式,因为它们是使用函数作用域实现的。这意味着以下操作将失败:

class A:
    a = 42
    b = list(a + i for i in range(10))
Run Code Online (Sandbox Code Playgroud)

显示列表、集合和字典

最左边子句中的可迭代表达式for直接在封闭范围内求值,然后作为参数传递给隐式嵌套范围。后续for子句和最左边for子句中的任何过滤条件都无法在封闭范围内求值,因为它们可能取决于从最左边可迭代获取的值。