在python类中引用self

时间:2011-10-03 22:39:32

标签: python reference

我认为这段代码应输出:

8
8

但事实并非如此。

class tree:
    def __init__(self, size=2):
        if size == 0:
            return None
        if size > 1:
            half = size//2
            self.left = tree(size-half)
            self.right = tree(half)
        else:
            self.left = self.right = None
        self.free = size
        self.size = size

    def resize(self,n):
        while self.size < n:
            t = tree(0)
            t.left = self
            t.right = tree(self.size)
            t.free = t.left.size + t.right.size
            t.size = self.size * 2
            self = t
        print("size in resize", self.size)

t = tree()
t.resize(5)
print("size of t", t.size)

输出:

size in resize 8
size of t 2

我知道我可以在return selfresize中使用t = tree.resize(5),但如果我想返回其他内容会怎么样?

2 个答案:

答案 0 :(得分:4)

Karl对所有事情的回答是完全正确的,但肯定有一种方法可以让resize按照您的期望行事。

三个步骤:

  1. 制作树的副本
  2. 重新初始化树,使其成为下一个更大的
  3. 将放大的树的left设置为原始树的副本

    def resize(self,n):
            while self.size < n:
                new = self.copy()
                self.__init__(int(round(self.size, 2)) * 2)
                self.left = new
    
            print("size in resize",self.size)
    
    def copy(self):
            new = tree(1)
            new.left = self.left
            new.right = self.right
            new.size = self.size
            new.free = self.free
            return new
    
  4. 基本上,您尝试向后执行此操作 - 替换self并重用self self.left,而不是替换self.left并重新使用self

答案 1 :(得分:2)

self = t

这不,无法重写,做你想做的事。关于Python中的名称self没有“特殊”;它就像任何其他变量一样(事实上你必须明确地将它传递给方法应该是你的第一个提示,不像将this视为关键字的语言,应该是你的第一个提示;)),像所有其他变量一样,它具有引用语义。

self = t表示“从此时开始(直到另一个重新定义或范围结束),self不再引用self参数引用的内容,而是指t引用的值“。

另外,你的__init__方法('rigt')的一个案例中有一个拼写错误,我假设free个节点的数量应该是{{1}的不变量}};在这种情况下,计算被占用的节点并使用方法或属性来计算空闲节点会更加清晰,而不是在每次修改时尝试更新该计数。

(而且,你似乎试图做的是各种非Pythonic。特别是,具有特定“分配大小”的容器的想法是奇怪的;这种事情通常只对C有关你需要一个二叉树吗?另外,这个方法根本不会平衡树。如果没有节点存储任何数据,那么树的用途是什么?)