什么时候一个班级的变化会反映在另一个班级?

时间:2017-11-21 09:15:41

标签: python class

我有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上。

我的问题是,为什么在第一个例子中,第一类的变化没有反映在第二类,而在第二个例子中,第一类的变化将反映在第二类?有一些规则吗?

2 个答案:

答案 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你仍然拥有之前生成的那个,因为它是指向该列表的唯一变量。

在你的第二个例子中,你存储你实例化的对象,而不是副本,所以相反的情况发生:两个变量都指向同一个对象,如果你使用这两个变量之一修改类的属性,你将会如果从另一个获得它们,则获得相同的属性。