Python类定义语法(括号)

时间:2019-12-08 11:55:41

标签: python

我发现大多数人都说在类定义中使用或不使用括号没有区别。但是我的代码为此输出了不同的结果。

#!/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

那么这背后的问题是什么

3 个答案:

答案 0 :(得分:1)

TLDR

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

但是,如果不调用构造函数,就不能实例化

类实例化和分配VERSUS类分配

这样做的时候

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个变量rootroot.leftroot.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.leftself.right,而总是指向self.dataTree.leftTree.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))

它们都将具有相同的值。