我有2节课。第二个类在类对象初始化期间接收第一个类作为参数。代码是:
import random
class DataSet(object):
def __init__(self, num):
self.num=num
self.data = self._gen_data()
def _gen_data(self):
return random.sample(list(range(100)), self.num)
def regenerate_data(self):
self.data = self._gen_data()
def show_data(self):
print(self.data)
class DataLoader(object):
def __init__(self, dataset):
self.data = dataset.data
def show_all_data(self):
print(self.data)
mydata = DataSet(num=5)
mydata.show_data()
myloader = DataLoader(dataset=mydata)
myloader.show_all_data()
mydata.regenerate_data()
mydata.show_data()
myloader.show_all_data()
如果我使用regenerate_data()
的{{1}}方法,我希望DataLoader对象也会显示已更改的数据。但显然,我错了。
mydata
中的更改未反映在mydata
上,myloader
仍显示旧数据。
然后我构建了第二个例子,
import random
class DataSet(object):
def __init__(self, num):
self.num=num
self.data = self._gen_data()
def _gen_data(self):
return random.sample(list(range(100)), self.num)
def __getitem__(self, index):
return self.data[index]
def regenerate_data(self):
self.data = self._gen_data()
def show_data(self):
print(self.data)
def __len__(self):
return len(self.data)
class DataLoader(object):
def __init__(self, dataset):
self.dataset = dataset
def show_batch(self):
print([self.dataset[i] for i in [0, 1]])
mydata = DataSet(num=5)
mydata.show_data()
myloader = DataLoader(dataset=mydata)
myloader.show_batch()
mydata.regenerate_data()
mydata.show_data()
myloader.show_batch()
现在,mydata
对象的更改会反映在myloader
上。
我的问题是,为什么在第一个例子中,第一类的变化没有反映在第二类,而在第二个例子中,第一类的变化将反映在第二类?有一些规则吗?
答案 0 :(得分:3)
在您的第一个示例中,regenerate_data()
仅返回新生成的数据,它不会将其分配给任何内容。在第二个示例中,由于myloader
包含对mydata
的引用,因此通过分配mydata
更改myloader
中的属性,也会在class ExampleClass:
def __init__(self):
self.data = 'foo'
def __str__(self):
return self.data
example = ExampleClass()
example.data = 'bar'
print(example)
中对其进行更改,因为它们会引用相同的对象
编辑:这是你如何测试你的类确实是可变的;
account = Stripe::Account.create({
:country => 'US',
:managed => true,
:transfer_schedule => {
:interval => 'weekly',
:weekly_anchor => 'friday'
},
:legal_entity => {
:dob => {
:day => birthday.day,
:month => birthday.month,
:year => birthday.year
},
:first_name => first_name,
:last_name => last_name,
:type => 'individual'
},
:tos_acceptance => {
:date => Time.now.to_i,
:ip => request.remote_ip
}
})
这告诉你什么?
答案 1 :(得分:1)
免责声明:答案不好。见另一个。
在第一个示例中,您使用的是:self.data = dataset.data
,而dataset.data
是由函数random.sample
生成的新列表。虽然确实如果你list1 = list2
指向同一个包含2个变量的列表,但random.sample
创建一个新变量,没有其他变量包含它,所以如果你生成另一个变量, self.data
你仍然拥有之前生成的那个,因为它是指向该列表的唯一变量。
在你的第二个例子中,你存储你实例化的对象,而不是副本,所以相反的情况发生:两个变量都指向同一个对象,如果你使用这两个变量之一修改类的属性,你将会如果从另一个获得它们,则获得相同的属性。