我发现大多数人都说在类定义中使用或不使用括号没有区别。但是我的代码为此输出了不同的结果。
#!/usr/bin/env python
class Tree(object):
def __init__(self):
self.left = None
self.right = None
self.data = None
root = Tree()
root.data = "root"
root.left = Tree()
root.left.data = "left"
root.right = Tree()
root.right.data = "right"
print(root.left.data)
Output: left
While
#!/usr/bin/env python
class Tree:
def __init__(self):
self.left = None
self.right = None
self.data = None
root = Tree
root.data = "root"
root.left = Tree
root.left.data = "left"
root.right = Tree
root.right.data = "right"
print(root.left.data)
Output : right
那么这背后的问题是什么
答案 0 :(得分:1)
class Tree: pass
# is "equivalent" to (in Python3)
class Tree(object): pass
# Class Declaration
但是
tree = Tree()
# is not the same as
tree = Tree
# Class instantiation
在类定义中(即
)没有区别class Tree(object): pass
与
class Tree: pass
但是,如果不调用构造函数,就不能实例化!
这样做的时候
tree = Tree() # instantiation AND assignment
您创建类Tree
的新对象并将分配给变量tree
。但是当您这样做时:
tree = Tree # ONLY assignment
您“仅 ”表示tree
引用了类 Tree
。从此以后,变量树的值为 class Tree
,而不是Tree
的实例。
因此,当您这样做
root = Tree
root.right = Tree
root.left = Tree
所有3个变量root
,root.left
和root.right
引用相同的对象,即类 Tree
。
因此,当您这样做时:
root.right.data = "right"
您不创建新对象,而是将 class Tree
分配给类变量root.right
(class属性),然后分配值{{1 }}到"right"
类的Tree
属性(类属性)。因此,由于对data
(作为一个类)的最后影响是Tree.data
,所以"right"
是Tree.data
。
⚠️令人困惑的是Python动态添加类属性的能力(选中此SO answer for explanations)。在第二个代码中,您永远不会指向"right"
,self.left
或self.right
,而总是指向self.data
,Tree.left
和Tree.right
。>
您可以签出:
Tree.data
您还可以检查:
class Tree: pass
root = Tree
root.data = "root"
root.left = Tree
root.left.data = "left"
root.right = Tree
root.right.data = "right"
print(root.data) # prints "right"
print(root.left.data) # prints "right"
print(root.right.data) # prints "right"
或者最后:
x = Tree()
print(x, type(x))
# <__main__.Tree object at 0x123456789> <class '__main__.Tree'>
y = Tree
print(y, type(y))
# <class '__main__.Tree'> <class 'type'>
答案 1 :(得分:0)
在Python 2中确实有所作为。所有类均从Python 3中的object
继承。请参见more details的以下答案:
无论如何,您都应该真的切换到Python 3,尤其是在您入门之前。 Python 2 will retire将于2020年1月1日发布。
答案 2 :(得分:0)
您说root=Tree
时,就是在将类Tree
分配给root。
代码
root = Tree
root.left = Tree
root.right = Tree
将根的左右分配给根本身。
由于最后一个分配是root.right.data = "right"
,因此root.data
被分配了值right
。
因此root.left.data
取值为right
。
您可以尝试打印以下内容:
print(id(root))
print(id(root.left))
print(id(root.right))
它们都将具有相同的值。