Python引用和循环
我习惯于perl,在perl中引用和变量是显式分开的。开始使用python会让生活变得非常混乱。我想在循环中工作,创建对象并将其添加到列表中,但结果令人沮丧。我读过函数定义变量范围的文章,但即使将循环代码封装在函数中,似乎也不能解决这个问题 例如:Python引用和循环,python,loops,object,variables,scope,Python,Loops,Object,Variables,Scope,我习惯于perl,在perl中引用和变量是显式分开的。开始使用python会让生活变得非常混乱。我想在循环中工作,创建对象并将其添加到列表中,但结果令人沮丧。我读过函数定义变量范围的文章,但即使将循环代码封装在函数中,似乎也不能解决这个问题 例如: mylist=[] 课程内容: 定义初始化(self,stuff=[]): self.stuff=stuff 对于范围(10)内的i: obj=事物() obj.stuff.append(1) mylist.append(obj) len(mylis
mylist=[]
课程内容:
定义初始化(self,stuff=[]):
self.stuff=stuff
对于范围(10)内的i:
obj=事物()
obj.stuff.append(1)
mylist.append(obj)
len(mylist[0]。stuff)
我希望每个对象的“stuff”列表的长度是1,但结果是10。我知道我可以使用deep copy显式地将新创建的对象与以前的对象区分开来,但是有没有更好的方法呢?这里的问题是,您有相同的
列表对象被用作使用thing()创建的所有对象的默认对象
一个可能的解决方案是不使用默认值,如下所示
class thing:
def __init__(self, stuff):
self.stuff = stuff
for i in range(10):
obj = thing(stuff = list())
print(id(obj.stuff))
这会在for循环的每次迭代中为stuff
成员分配一个新的列表。这里的问题是,您使用相同的列表
对象作为使用thing()创建的所有对象的默认对象
一个可能的解决方案是不使用默认值,如下所示
class thing:
def __init__(self, stuff):
self.stuff = stuff
for i in range(10):
obj = thing(stuff = list())
print(id(obj.stuff))
这会在for循环的每次迭代中为stuff
成员分配一个新的列表
。当可变列表对象被定义为参数时,它会传递给类
课程内容:
定义初始化(self,stuff=[]):
self.stuff=stuff
对于范围(10)内的i:
obj=事物()
打印(obj)
obj.stuff.append(1)
打印(对象内容)
mylist.append(obj)
打印(mylist)
[1]
[]
[1, 1]
[,]
[1, 1, 1]
[,]
[1, 1, 1, 1]
[,]
[1, 1, 1, 1, 1]
[,]
[1, 1, 1, 1, 1, 1]
[,,]
[1, 1, 1, 1, 1, 1, 1]
[,,]
[1, 1, 1, 1, 1, 1, 1, 1]
[,,,]
[1, 1, 1, 1, 1, 1, 1, 1, 1]
[,,,]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[,,,,,]
在功能块内实例化列表时,每次都会创建一个新列表
下面是使用下面的类时的输出
类事物:
__初始化(self,stuff):
如果是:
self.stuff=stuff
其他:
self.stuff=[]
对于范围(10)内的i:
obj=事物()
打印(obj)
obj.stuff.append(1)
打印(对象内容)
mylist.append(obj)
打印(mylist)
输出
[1]
[]
[1]
[,]
[1]
[,]
[1]
[,]
[1]
[,]
[1]
[,,]
[1]
[,,]
[1]
[,,,]
[1]
[,,,]
[1]
[,,,,,]尝试一下,当可变列表对象被定义为参数时,它会传递给类
课程内容:
定义初始化(self,stuff=[]):
self.stuff=stuff
对于范围(10)内的i:
obj=事物()
打印(obj)
obj.stuff.append(1)
打印(对象内容)
mylist.append(obj)
打印(mylist)
[1]
[]
[1, 1]
[,]
[1, 1, 1]
[,]
[1, 1, 1, 1]
[,]
[1, 1, 1, 1, 1]
[,]
[1, 1, 1, 1, 1, 1]
[,,]
[1, 1, 1, 1, 1, 1, 1]
[,,]
[1, 1, 1, 1, 1, 1, 1, 1]
[,,,]
[1, 1, 1, 1, 1, 1, 1, 1, 1]
[,,,]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[,,,,,]
在功能块内实例化列表时,每次都会创建一个新列表
下面是使用下面的类时的输出
类事物:
__初始化(self,stuff):
如果是:
self.stuff=stuff
其他:
self.stuff=[]
对于范围(10)内的i:
obj=事物()
打印(obj)
obj.stuff.append(1)
打印(对象内容)
mylist.append(obj)
打印(mylist)
输出
[1]
[]
[1]
[,]
[1]
[,]
[1]
[,]
[1]
[,]
[1]
[,,]
[1]
[,,]
[1]
[,,,]
[1]
[,,,]
[1]
这是Python的一个怪癖。在定义函数时,参数的默认值只构造一次。所以,你可以得到这种奇怪的行为:
def f(x=[]):
x.append('x')
return x
f()
# ['x']
f()
# ['x', 'x']
f()
# ['x', 'x', 'x']
将[]
替换为list()
,将不会有任何帮助,因为在定义函数时,仍然只对其求值一次。然后,每次调用函数时,同一对象将被重新用作默认对象
为了避免这种情况,您需要使用sentinel,然后显式测试它是否被覆盖。这是一种常见的模式:
def f(x=None):
if x is None:
x = []
x.append('x')
return x
f()
# ['x']
f()
# ['x']
f(['a', 'b'])
# ['a', 'b', 'x']
这是Python的一个怪癖。在定义函数时,参数的默认值只构造一次。所以,你可以得到这种奇怪的行为:
def f(x=[]):
x.append('x')
return x
f()
# ['x']
f()
# ['x', 'x']
f()
# ['x', 'x', 'x']
将[]
替换为list()
,将不会有任何帮助,因为在定义函数时,仍然只对其求值一次。然后,每次调用函数时,同一对象将被重新用作默认对象
为了避免这种情况,您需要使用sentinel,然后显式测试它是否被覆盖。这是一种常见的模式:
def f(x=None):
if x is None:
x = []
x.append('x')
return x
f()
# ['x']
f()
# ['x']
f(['a', 'b'])
# ['a', 'b', 'x']
这回答了你的问题吗?这回答了你的问题吗?谢谢大家-我正在慢慢习惯这条蛇的运作方式谢谢大家-我正在慢慢习惯这条蛇的运作方式