开发者

References in python classes on self

开发者 https://www.devze.com 2023-04-10 03:22 出处:网络
I expet that this code should output: 8 8 but it does not. class tree: def __init__(self, size=2): if size == 0:

I expet that this code should output:

8

8

but it does not.

class tree:
    def __init__(self, size=2):
        if size == 0:
            return Non开发者_如何学JAVAe
        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)

output:

size in resize 8
size of t 2

I know I could do return self in resize and t = tree.resize(5) in main, but what if I want to return something else?


Karl's answer is entirely right about everything, but there is certainly a way to make resize act as you're expecting.

Three steps:

  1. Make a copy of the tree
  2. Re-initialize the tree so it's the next size larger
  3. Set the enlarged tree's left to the copy of the original tree

    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
    

Basically, you were trying to do it backwards -- replace self and reuse self for self.left, instead of replacing self.left and reusing self.


self = t

This does not, and cannot be rewritten to, do what you want. There is nothing "special" about the name self in Python; it's just like any other variable (the fact that you have to pass it explicitly to methods should have been your first hint, unlike in languages that treat this as a keyword, should have been your first hint ;) ), and like all other variables, it has reference semantics.

self = t means "from this point onward (until another re-definition or the end of scope), self no longer refers to what that self parameter referred to, but instead to the value that t refers to".

Also, you have a typo in one case of your __init__ method ('rigt'), and I assume that the number of free nodes is supposed to be an invariant something like size - occupied; in which case it would be cleaner to count the occupied nodes and use a method or property to calculate the free ones, instead of trying to update that count on every modification.

(Moreover, what you seem to be trying to do is all kinds of un-Pythonic. In particular, the idea of a container having a specific "allocated size" is strange; that sort of thing normally only matters on the C side of the fence. What do you need a binary tree for? Also, this method isn't going to balance the tree at all. And what use is a tree if none of the nodes store any data?)

0

精彩评论

暂无评论...
验证码 换一张
取 消