Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.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 - Fatal编程技术网

Python 类变量的行为因其类型而异(共享或不共享)

Python 类变量的行为因其类型而异(共享或不共享),python,Python,当用作类变量时,数字和列表的行为不同:数字不与实例共享,而列表变量是共享的。(在相同条件下)有人能解释发生了什么事吗 Ps:已经问过这个问题(解释得不太清楚),它被认为是关于类变量的问题的重复。我在问为什么在相同的条件下,数字和列表类变量之间存在差异 class test_class: number = 0 list = [8] def addnum(self, num): self.number = num def addlist(self, l

当用作类变量时,数字和列表的行为不同:数字不与实例共享,而列表变量是共享的。(在相同条件下)有人能解释发生了什么事吗

Ps:已经问过这个问题(解释得不太清楚),它被认为是关于类变量的问题的重复。我在问为什么在相同的条件下,数字和列表类变量之间存在差异

class test_class:
    number = 0
    list = [8]
    def addnum(self, num):
        self.number = num
    def addlist(self, list):
        self.list.append(list)
object = test_class()
object.addnum(5)
object.addlist(6)

print(test_class.number)
print(object.number)

print(test_class.list)
print(object.list)
这张照片是:

0
5         (number variable is not shared)
[8, 6]    (list was shared)
[8, 6]
------
[8]
[6]
------
[8]
[6, 2]
------
[8]
[8]
------
[8, 3]
[8, 3]
预期:

0
5
[8]
[8, 6] (list gets appended without affecting the original)

类变量应该被视为一种全局变量:存储整个类的全局状态的位置(很少需要),以及定义共享常量的位置(非常常见)。如果希望实例的数据因实例而异,请在
\uuu init\uuu()方法中设置它们,而不是在类级别


就您观察到的差异而言,在一种情况下,您为属性指定了一个值,而在另一种情况下,您对已存储在属性中的值进行了变异。核心问题是赋值变异之间的区别

类变量应被视为一种全局变量:存储整个类的全局状态的位置(很少需要),以及定义共享常量的位置(非常常见)。如果希望实例的数据因实例而异,请在
\uuu init\uuu()方法中设置它们,而不是在类级别


就您观察到的差异而言,在一种情况下,您为属性指定了一个值,而在另一种情况下,您对已存储在属性中的值进行了变异。核心问题是分配变异

之间的区别。完成分配看起来解决了问题,但我认为还有更多问题。 为self.list赋值时,将创建一个新的单独实例变量(与数字一样),它是self.list的新引用,删除时,类将返回其旧的list类变量。追加是共享的,因为我们保留类变量,而不是创建实例,这段代码对我解释得很好:

class test_class:
list = [8]
def addlist(self, liste):
    self.list= [liste]
def appendlist(self,new):
    self.list.append(new)
def delete(self):
    del self.list


object = test_class()

object.addlist(6) ## this creates a new and separate instance variable
print("------")
print(test_class.list)
print(object.list)


object.appendlist(2)  ## adds up to the instance variable
print("------")
print(test_class.list)
print(object.list)

object.delete()    ## deleting the instance var shows that the class var is still there
print("------")
print(test_class.list)
print(object.list)

object.appendlist(3)  ##class variable gets appended to, since we're not asking to create a new one
print("------")
print(test_class.list)
print(object.list)
这张照片是:

0
5         (number variable is not shared)
[8, 6]    (list was shared)
[8, 6]
------
[8]
[6]
------
[8]
[6, 2]
------
[8]
[8]
------
[8, 3]
[8, 3]

谢谢你的回答

做作业看起来解决了问题,但我认为还有更多问题。 为self.list赋值时,将创建一个新的单独实例变量(与数字一样),它是self.list的新引用,删除时,类将返回其旧的list类变量。追加是共享的,因为我们保留类变量,而不是创建实例,这段代码对我解释得很好:

class test_class:
list = [8]
def addlist(self, liste):
    self.list= [liste]
def appendlist(self,new):
    self.list.append(new)
def delete(self):
    del self.list


object = test_class()

object.addlist(6) ## this creates a new and separate instance variable
print("------")
print(test_class.list)
print(object.list)


object.appendlist(2)  ## adds up to the instance variable
print("------")
print(test_class.list)
print(object.list)

object.delete()    ## deleting the instance var shows that the class var is still there
print("------")
print(test_class.list)
print(object.list)

object.appendlist(3)  ##class variable gets appended to, since we're not asking to create a new one
print("------")
print(test_class.list)
print(object.list)
这张照片是:

0
5         (number variable is not shared)
[8, 6]    (list was shared)
[8, 6]
------
[8]
[6]
------
[8]
[6, 2]
------
[8]
[8]
------
[8, 3]
[8, 3]

谢谢你的回答

没有区别。如果您执行了
self.list=something
,您将看到与int相同的行为。没错,谢谢!它们是类变量而不是实例变量,因为您没有通过_uinit__;()方法定义它们;这是非常不寻常的,而且通常是个坏主意。接下来,当你真正的意思是
set\u num
addlist
时,请不要调用你的方法
addnum
append\u list
,因为它们显然做了两件截然不同的事情;一个是setter,另一个尝试附加(一个特定于实例的参数,附加到一个类变量-这充其量是折磨,最坏的是毫无意义)。(类变量
list=[8]
;对我来说似乎没有什么意义?)你是对的,我没有仔细考虑函数名,只是为了示例而编的。对于list类变量来说,它是用来测试它是如何工作的。就是这样,更好地理解机制是防止以后出现问题的最好方法,我想(而不是像你建议的那样只使用实例变量)没有区别。如果您执行了
self.list=something
,您将看到与int相同的行为。没错,谢谢!它们是类变量而不是实例变量,因为您没有通过_uinit__;()方法定义它们;这是非常不寻常的,而且通常是个坏主意。接下来,当你真正的意思是
set\u num
addlist
时,请不要调用你的方法
addnum
append\u list
,因为它们显然做了两件截然不同的事情;一个是setter,另一个尝试附加(一个特定于实例的参数,附加到一个类变量-这充其量是折磨,最坏的是毫无意义)。(类变量
list=[8]
;对我来说似乎没有什么意义?)你是对的,我没有仔细考虑函数名,只是为了示例而编的。对于list类变量来说,它是用来测试它是如何工作的。我想,更好地理解机制是防止以后出现问题的最好方法(而不是像你建议的那样只使用实例变量),尽管这些信息是正确的,它没有回答这个问题。@user2357112:从技术上讲,它提供的信息如果拼凑在一起就可以回答这个问题,但不会以任何新用户都能理解的方式提供。需要更具规范性的“你做错了,因为你的类在类级别用代码初始化成员;它没有在每个实例上调用的
\uuuu init\uuuu()
”。作为代码错误的证明,现在该类的所有实例共享相同的
.list
成员:
object.list,obj2.list…
。这通常没有意义,每个实例都应该与其他实例“隔离”,所以只需声明一个
\uuu init\uuu()
。我知道关于实例变量,问题是关于类变量的,谢谢大家的贡献!虽然这些信息是真实的,但它并不能回答问题。@user2357112:从技术上讲,它提供的信息如果拼凑在一起就可以回答问题,但不能用w