Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么实例变量在此代码中引用相同的对象?_Python_Instance Variables_Python Class - Fatal编程技术网

Python 为什么实例变量在此代码中引用相同的对象?

Python 为什么实例变量在此代码中引用相同的对象?,python,instance-variables,python-class,Python,Instance Variables,Python Class,我想在has-a关系中的Shape类中实现move方法(这样Shape类就不会继承CPoint类),但在设置类变量时遇到问题 给定的代码是: class CPoint: def __init__(self, x = 0, y = 0): self.__x = x self.__y = y def __str__(self): return f"pos({self.__x},{self.__y})"

我想在has-a关系中的Shape类中实现move方法(这样Shape类就不会继承CPoint类),但在设置类变量时遇到问题

给定的代码是:

class CPoint:
    def __init__(self, x = 0, y = 0):
        self.__x = x
        self.__y = y
    
    def __str__(self):
        return f"pos({self.__x},{self.__y})"
    
    def get_x(self):
        return self.__x
    
    def set_x(self, new_x):
        self.__x = new_x
    
    def get_y(self):
        return self.__y
    
    def set_y(self, new_y):
        self.__y = new_y
    
    def move(self, a, b):
        self.__x += a
        self.__y += b
        return CPoint(self.__x,self.__y)
    

class Shape:
    def __init__(self, color = "yellow", filled = True, pos = CPoint()): 
        #So each pos must reference the different CPoint() instance 
        self.__color = color
        self.__filled = filled
        self.__pos = pos
    
    def __str__(self):
        return f"{self.__pos}({self.__color},{self.__filled})"
    
    def move(self, a, b):
        self.__pos.move(a,b)
        
        if type(self) == Shape:
            return f"{self}"
        else:
            return f"{self.__pos}{self}"


def main():
    a = Shape()
    b = Shape("red")
    a.move(2,3)
    print(b.move(4,5))
    
main()
结果是:

pos(0,0)(yellow,True)
pos(0,0)(red,True)
pos(2,3)(yellow,True)
pos(6,8)(red,True)
结果应该是:

pos(0,0)(yellow,True)
pos(0,0)(red,True)
pos(2,3)(yellow,True)
pos(4,5)(red,True)
我在python教程上执行了代码,代码的可视化如下:

因此Shape()和Shape(“red”)对象应该引用不同的CPoint实例(因为它们有自己的位置数据),但它们引用相同的实例,即使我设置了默认参数,如“pos=CPoint()”


有人能解释一下他们为什么要引用同一个实例,以及如何绕过它吗?

这是python默认参数的方式,默认参数在函数声明期间初始化一次,而不是像您使用其他语言(如Javascript)时所期望的那样,每次调用函数时都初始化一次

因此,相同的
CPoint()
实例在不同的构造函数调用之间共享

要避免这种行为,可以尝试在函数本身内部设置它

类形状:
定义初始值(self,color=“yellow”,filled=True,pos=None):
如果pos为无:
pos=CPoint()
#因此,每个pos必须引用不同的CPoint()实例
自身颜色=颜色
自填充=填充
自身位置=位置

我猜是因为自我的类型总是形状?!在
中,如果type(self)==Shape:
它是对自身的引用,因此始终是ShapeTrue@Ivonet原始代码中还有其他类,如圆形或矩形,因此需要该语句。我想我在构造器部分有一个问题…但是pos是一个arg,它需要在关键字args之前,或者应该有一个默认值…我的错,我用正确的修复更新了答案。非常感谢。这正是我想要的。