Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.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类,为什么要在getters中返回obj的副本?_Python_Class_Getter - Fatal编程技术网

Python类,为什么要在getters中返回obj的副本?

Python类,为什么要在getters中返回obj的副本?,python,class,getter,Python,Class,Getter,我知道我们使用getter和setter来防止用户直接修改类的数据属性。但为什么我们必须在getter中返回一个副本或不可变对象呢?如果返回值是可变的,用户是否可以改变这些变量 def get_encryption_dict(self): ''' Used to safely access a copy self.encryption_dict outside of the class Returns: a COPY of

我知道我们使用getter和setter来防止用户直接修改类的数据属性。但为什么我们必须在getter中返回一个副本或不可变对象呢?如果返回值是可变的,用户是否可以改变这些变量

    def get_encryption_dict(self):
        '''
        Used to safely access a copy self.encryption_dict outside of the class
        
        Returns: a COPY of self.encryption_dict
        '''
        return self.encryption_dict.copy()


是的,在python中(和在其他语言中一样)需要小心,因为有些对象是可变的。最重要和最常见的情况是集合类型,如
list
dict

例如,如果示例中的代码是此代码,那么它将返回对字典的可变引用

return self.encryption_dict#警告,不要在家里/在自己的类代码中这样做,返回可变引用,oyu可能不想要它!
返回self.some_other_internal_list#相同的警告!
但为什么我们必须在getter中返回一个副本或不可变对象呢?如果返回值是可变的,用户是否可以改变这些变量

    def get_encryption_dict(self):
        '''
        Used to safely access a copy self.encryption_dict outside of the class
        
        Returns: a COPY of self.encryption_dict
        '''
        return self.encryption_dict.copy()

对!!例如,对返回的dict调用
.clear()
,将清除对象使用的内部字典。。。哎呀

您可以轻松地复制可枚举列表或字典,如代码示例中所示:使用所有字典的
.copy()
复制到,使用
[:]
复制列表

return self.encryption_dict.copy()#这里的风险小得多,对象的内部字典无法修改,它是返回的(浅)副本。
返回self.some_other_internal_list[:]#好的,“[:]”实际上创建了一个列表的副本。
正如在注释中所注意到的,请注意,如果一个对象是可变的,那么获得列表的正确副本仍然会暴露对同一对象的引用,这可能是意外的。(这就是为什么我们称这些为“浅”拷贝,与“深”拷贝相对)


根据经验法则,不变性将保护您免受细微(或不太细微)的bug。

python不强制在“getter”/property中返回副本,只是您的用例需要返回一个copy简短的回答:是的,如果您返回一个可变对象,用户可以修改它。不仅如此,即使您返回一个副本或不可变对象,用户也可能会改变该对象中的元素,例如字典的值(键无论如何都应该是不可变的)。请将代码复制为有问题的文本,而不是[粘贴为图像]。那么,如果返回的是列表或dict,该怎么办?我应该使用deepcopy吗?或者将它们转换为字符串?使用浅拷贝是很好的第一步。创建深度拷贝可能一点也不琐碎。一个好的折衷办法是返回一个不可变对象的列表或字典。但我想我们需要一个更详细的例子来决定。