Python OOP 和列表

发布于 2024-09-02 04:44:48 字数 1238 浏览 2 评论 0原文

我是 Python 新手,它是 OOP 的东西,无法让它工作。这是我的代码:

class Tree:

    root = None;
    data = [];

    def __init__(self, equation):
        self.root = equation;

    def appendLeft(self, data):
        self.data.insert(0, data);

    def appendRight(self, data):
        self.data.append(data);

    def calculateLeft(self):
        result = [];
        for item in (self.getLeft()):
            if (type(item) == type(self)):
                data = item.calculateLeft();
            else:
                data = item;
            result.append(item);
        return result;

    def getLeft(self):
        return self.data;

    def getRight(self):
        data = self.data;
        data.reverse();
        return data;

tree2 = Tree("*");
tree2.appendRight(44);
tree2.appendLeft(20);

tree = Tree("+");
tree.appendRight(4);
tree.appendLeft(10);
tree.appendLeft(tree2);

print(tree.calculateLeft());

看起来tree2和tree正在共享列表“数据”?

目前,我希望它输出类似 [[20,44], 10, 4] 的内容,但是当我

tree.appendLeft(tree2) 

得到 RuntimeError: Maximum recursion Deepisoded 时,当我什至不会时appendLeft(tree2) 它输出 [10, 20, 44, 4] (!!!)。我在这里缺少什么?我正在使用可移植Python 3.0.1。

谢谢

I'm new to Python and it's OOP stuff and can't get it to work. Here's my code:

class Tree:

    root = None;
    data = [];

    def __init__(self, equation):
        self.root = equation;

    def appendLeft(self, data):
        self.data.insert(0, data);

    def appendRight(self, data):
        self.data.append(data);

    def calculateLeft(self):
        result = [];
        for item in (self.getLeft()):
            if (type(item) == type(self)):
                data = item.calculateLeft();
            else:
                data = item;
            result.append(item);
        return result;

    def getLeft(self):
        return self.data;

    def getRight(self):
        data = self.data;
        data.reverse();
        return data;

tree2 = Tree("*");
tree2.appendRight(44);
tree2.appendLeft(20);

tree = Tree("+");
tree.appendRight(4);
tree.appendLeft(10);
tree.appendLeft(tree2);

print(tree.calculateLeft());

It looks like tree2 and tree are sharing list "data"?

At the moment I'd like it to output something like [[20,44], 10, 4], but when I

tree.appendLeft(tree2) 

I get RuntimeError: maximum recursion depth exceeded, and when i even won't appendLeft(tree2) it outputs [10, 20, 44, 4] (!!!). What am I missing here? I'm using Portable Python 3.0.1.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌︼了一个春 2024-09-09 04:44:48

问题是您已将 data 声明为类变量,因此该类的所有实例共享相同的列表。相反,请将 self.data = [] 放入 __init__ 中。

另外,去掉所有那些分号。它们是不必要的并且会使您的代码变得混乱。

The problem is that you've declared data as a class variable, so all instances of the class share the same list. Instead, put self.data = [] in your __init__.

Also, get rid of all those semicolons. They are unnecessary and clutter up your code.

空城之時有危險 2024-09-09 04:44:48

将 root 和数据移动到 __init__ 的定义中。按照目前的情况,您将它们定义为类属性。这使得它们在 Tree 类的所有实例之间共享。当您实例化两棵树(treetree2)时,它们都共享使用 self.data 访问的同一列表。要使每个实例都有自己的实例属性,必须将声明移至 __init__ 函数中。

def __init__(self, equation):
    self.root = equation
    self.data = []

另外,

        if isinstance(item,Tree):        # This is True if item is a subclass of Tree

使用代替

        if (type(item) == type(self)):   # This is False if item is a subclass of Tree

并更改

data = self.data

data = self.data[:]

getRight 中 。当您说 data = self.data 时,变量名称 data 所指向的列表与 self.data 所指向的列表完全相同。
当您随后反转data时,您也会反转self.data
要仅反转数据,您必须复制该列表。 self.data[:] 使用切片表示法返回列表的副本。请注意,self.data 的元素可以是 Tree,以及 self.dataself.data[:] 可以包含相同的元素。我认为您的代码不需要复制这些元素,但如果是这种情况,您将需要递归复制 self.data

def getRight(self):
    data = self.data[:]
    data.reverse()
    return data

Move root and data into the definition of __init__ . As it stands, you have them defined as class attributes. That makes them shared among all instances of the Tree class. When you instantiate two Trees (tree and tree2), they both share the same list accessed with self.data. To make each instance have its own instance attribute, you must move the declaration into the __init__ function.

def __init__(self, equation):
    self.root = equation
    self.data = []

Also, use

        if isinstance(item,Tree):        # This is True if item is a subclass of Tree

instead of

        if (type(item) == type(self)):   # This is False if item is a subclass of Tree

and change

data = self.data

to

data = self.data[:]

in getRight. When you say data = self.data then the variable name data points at the very same list that self.data points at.
When you subsequently reverse data, you reverse self.data as well.
To reverse only data, you must copy the list. self.data[:] uses slicing notation to return a copy of the list. Note that the elements of self.data can be Trees, and self.data and self.data[:] can contain identical elements. I don't think your code requires these elements to be copied, but you'll need to recursively copy self.data if that is the case.

def getRight(self):
    data = self.data[:]
    data.reverse()
    return data
故人爱我别走 2024-09-09 04:44:48

当您按以下方式定义属性时:

class Tree:
    root = None
    data = []

..该空列表对象是在 Python 定义类时创建的,而不是在您创建新实例时创建的。它是一个类属性,而不是实例属性。这意味着,Tree.root 在所有实例中都是同一个对象:

class Tree:
    root = None
    data = []

t1 = Tree()
t2 = Tree()

print id(t1.data) == id(t2.data) # is True, they are the same object

要获得您期望的行为,请将空列表的创建移至 __init__ 函数,该函数仅被调用当您创建新实例时,并且仅更改该实例(因为它分配给 self):

class Tree:
    def __init__(self):
        self.root = None
        self.data = []

t1 = Tree()
t2 = Tree()

print id(t1.data) == id(t2.data) # False, they are different objects

这个问题解释了为什么这种行为可能有用

When you define attributes in the following way:

class Tree:
    root = None
    data = []

..that empty list object is created as Python defines the class, not when you create a new instance. It is a class attribute, not an instance attribute. Meaning, Tree.root is the same object in all instances:

class Tree:
    root = None
    data = []

t1 = Tree()
t2 = Tree()

print id(t1.data) == id(t2.data) # is True, they are the same object

To get the behaviour you expect, move the creation of the empty list to the __init__ function, which is only called when you create a new instance, and only alters that instance (as it assigns to self):

class Tree:
    def __init__(self):
        self.root = None
        self.data = []

t1 = Tree()
t2 = Tree()

print id(t1.data) == id(t2.data) # False, they are different objects

This question explains why such behaviour can be useful

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文