Python类定义语法(括号)

2024-04-26 08:04:05 发布

您现在位置: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

那么这背后的问题是什么呢


Tags: selfrightenvnonetreedatabininit
3条回答

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

但是,如果不调用构造函数,就不能实例化!你知道吗

类实例化和赋值与类赋值

当你这么做的时候

tree = Tree() # instantiation AND assignment

创建一个类Tree的新对象,并将其赋给变量tree。但当你这么做的时候:

tree = Tree # ONLY assignment

你“”说tree引用了Tree。此后,变量树的值是Tree,而不是Tree的实例。你知道吗

因此,当你

root = Tree
root.right = Tree
root.left = Tree

所有3个变量rootroot.leftroot.right都引用同一个对象,Tree。你知道吗

所以当你这么做的时候:

root.right.data = "right"

不创建新对象,而是将Tree赋给类变量root.right(class属性),然后将值"right"赋给Tree类的data属性(class属性)。因此,由于对Tree.data(作为一个类)的最后一个假装是"right",那么Tree.data就是"right"。你知道吗

另外

你知道吗⚠️ 让人困惑的是Python动态添加类属性的能力(请检查这个SO answer for explanations)。在第二段代码中,您从不指向self.leftself.rightself.data,而是始终指向Tree.leftTree.rightTree.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'>

或者最后:

class Tree: pass

root = Tree
root.left = Tree
print(root == root.left) # True, because references the class

root = Tree()
root.left = Tree()
print(root == root.left) # False, because references two different instances

当您说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))

它们都有相同的值。你知道吗

在Python2中,它确实起到了作用。所有类都继承自python3中的object。参见more details的答案:

无论如何,您应该真的切换到python3,特别是在您刚开始的时候。Python 2will retire于2020年1月1日发布。你知道吗

相关问题 更多 >