为什么 `lambda: MyClass()` 是合法的,但 `MyClass()` 本身是非法的?
Why `lambda: MyClass()` is legal but `MyClass()` itself is illegal?
以下代码是合法的:
class MyClass:
print(lambda: MyClass())
class MyClass:
print(lambda: self())
class MyClass:
children = defaultdict(lambda: MyClass())
mc = MyClass()
print(mc.children)
cc = mc.children[0]
print(cc.children)
但是,下面的代码是非法的:
class MyClass:
def f(): return MyClass()
print(f()) #=> NameError: name 'MyClass' is not defined
class MyClass:
children = MyClass() #=> NameError: name 'MyClass' is not defined
class MyClass:
children = self() #=> NameError: name 'self' is not defined
我的问题是,为什么 MyClass
和 self
一旦包裹在 lambda 中就变成 defined
?
(我在玩 Trie 结构并试图理解为什么 TrieNode 必须定义为单独的 class。TrieNode 基本上是用 children = defaultdict(lambda: TrieNode())
定义的单行 class)
传递给 defaultdict
的工厂函数:
class TrieNode:
children = defaultdict(lambda: TrieNode())
在 class 定义期间未被调用。一旦 class 被定义,该函数就可以从封闭的命名空间访问 class 名称。以下将失败并出现与您遇到的类似错误:
class TrieNode:
children = defaultdict(lambda: TrieNode())
children[4] # calls factory function before class is defined!
NameError: name 'TrieNode' is not defined
一个更生动的例子来说明封闭的命名空间事实:
class TrieNode:
children = defaultdict(lambda: TrieNode())
t = TrieNode()
TrieNode = int
t.children[5]
# 0
# [sic!] ...
# ... t is still a TrieNode from the earlier class definiton,
# but the factory function uses the latter override from the enclosing namespace
以下代码是合法的:
class MyClass:
print(lambda: MyClass())
class MyClass:
print(lambda: self())
class MyClass:
children = defaultdict(lambda: MyClass())
mc = MyClass()
print(mc.children)
cc = mc.children[0]
print(cc.children)
但是,下面的代码是非法的:
class MyClass:
def f(): return MyClass()
print(f()) #=> NameError: name 'MyClass' is not defined
class MyClass:
children = MyClass() #=> NameError: name 'MyClass' is not defined
class MyClass:
children = self() #=> NameError: name 'self' is not defined
我的问题是,为什么 MyClass
和 self
一旦包裹在 lambda 中就变成 defined
?
(我在玩 Trie 结构并试图理解为什么 TrieNode 必须定义为单独的 class。TrieNode 基本上是用 children = defaultdict(lambda: TrieNode())
定义的单行 class)
传递给 defaultdict
的工厂函数:
class TrieNode:
children = defaultdict(lambda: TrieNode())
在 class 定义期间未被调用。一旦 class 被定义,该函数就可以从封闭的命名空间访问 class 名称。以下将失败并出现与您遇到的类似错误:
class TrieNode:
children = defaultdict(lambda: TrieNode())
children[4] # calls factory function before class is defined!
NameError: name 'TrieNode' is not defined
一个更生动的例子来说明封闭的命名空间事实:
class TrieNode:
children = defaultdict(lambda: TrieNode())
t = TrieNode()
TrieNode = int
t.children[5]
# 0
# [sic!] ...
# ... t is still a TrieNode from the earlier class definiton,
# but the factory function uses the latter override from the enclosing namespace