class Node:
def append_child(self, node: Node):
if node != None:
self.first_child = node
self.child_nodes += [node]
我如何node: Node
?因为当我运行它时,它会显示name 'Node' is not defined
。
我应该删除: Node
并在函数内部检查实例吗?
但是,我怎样才能访问node
的属性(我希望它是Node
类的实例)?
我不知道如何在Python中实现类型转换,BTW。
答案 0 :(得分:15)
类型检查中的“self”引用通常使用字符串完成:
class Node:
def append_child(self, node: 'Node'):
if node != None:
self.first_child = node
self.child_nodes += [node]
PEP-0484的"Forward references"部分对此进行了描述。
请注意这不会进行任何类型检查或投射。这是类型提示,python(通常)完全忽略 1 。但是,第三方工具(例如mypy)使用类型提示对代码进行静态分析,并在运行之前生成错误。
1 提示是内省的 - 所以你可以使用它们来构建某种运行时检查器,如果你真的想要使用装饰器等,但python默认不这样做。
答案 1 :(得分:6)
从Python 3.7开始,您可以Python通过PEP 563实现类型注释的推迟评估。在PEP 563下,注释以字符串形式存储在typedef unsigned char u8;
template <u8 N>
class matrix {
public:
matrix(std::array<std::array<int, N>, N> l);
private:
std::array<std::array<int, N>, N> arr;
};
template <u8 N>
matrix<N>::matrix(std::array<std::array<int, N>, N> l) : arr(l) {}
int main()
{
std::array<std::array<int, 2>, 2> arr{{{{1, 2}}, {{3, 4}}}}; // this is how you have to initialize a 2d std::array
matrix<2> m = {{{{{1, 2}}, {{3, 4}}}}}; // we need one more brace here since we are initialzing the matrix, which needs its own brace
}
中。从Python 3.7开始,您可以通过__future__
指令启用此功能:
__annotations__
这使得可以编写:
from __future__ import annotations
从Python 4.0开始,此行为将是正常行为。
答案 2 :(得分:1)
如果您只想回答问题,请阅读mgilson's answer。
mgilson的回答提供了一个很好的解释,说明如何解决Python的这种限制。但我认为理解为什么这不起作用也很重要,所以我将提供解释。
Python与其他语言略有不同。在Python中,真的没有&#34;声明。&#34;声明。&#34;就Python而言,代码只是代码。导入模块时,Python会创建一个新的命名空间(全局变量可以存在的位置),然后从上到下执行模块的每一行。 def foo(args): code
只是一个复合语句,它将一堆源代码捆绑在一起,并将该函数绑定到名称foo
。类似地,class Bar(bases): code
创建一个类,立即执行所有代码(在一个单独的命名空间内,该命名空间包含可能由代码创建的任何类级变量,尤其包括使用{创建的方法) {1}}),然后将该类绑定到名称def
。它必须立即执行代码,因为需要立即创建所有方法。因为代码在绑定名称之前执行,所以您无法在代码的顶层引用该类。但是,引用方法内部的类是完全正确的,因为该代码在调用方法之前不会运行。
(您可能想知道为什么我们不能先绑定名称然后执行代码。事实证明,由于Python实现类的方式,您必须先了解哪些方法存在,之前您甚至可以创建类对象。可以创建一个空类,然后使用属性赋值将所有方法一次绑定到它(实际上,您可以通过编写Bar
手动执行此操作然后执行class Bar: pass
等等,但这会导致更复杂的实现,并且更难以概念化,因此Python不会这样做。)
总结代码:
def method1():...; Bar.method1 = method1
答案 3 :(得分:1)
在Python> 3.7中,您可以使用数据类。您还可以注释数据类。
在此特定示例中,Node引用了自己,您将获得它,如果运行它,您将得到
NameError: name 'Node' is not defined
要克服此错误,您必须添加:
from __future__ import annotations
它必须是模块中的第一行。在Python 4.0及更高版本中,您不必包含annotations
from __future__ import annotations
from dataclasses import dataclass
@dataclass
class Node:
value: int
left: Node
right: Node
@property
def is_leaf(self) -> bool:
"""Check if node is a leaf"""
return not self.left and not self.right
示例:
node5 = Node(5, None, None)
node25 = Node(25, None, None)
node40 = Node(40, None, None)
node10 = Node(10, None, None)
# balanced tree
node30 = Node(30, node25, node40)
root = Node(20, node10, node30)
# unbalanced tree
node30 = Node(30, node5, node40)
root = Node(20, node10, node30)