Python类对象实例是如何传递给函数的?Python中的类实例是按引用传递还是按值传递



我在SO上没有看到任何关于这方面的问题,所以我想问一下Python类对象实例是如何传递到函数中的,以及它在函数中的行为。我对运行这个片段时的行为有一些怀疑:

(注意:我知道有更好的方法可以实现这个例子中的相同行为。我的实际用例涉及稍微复杂一点的操作:线程等。我只是更感兴趣的是了解传递的参数到底发生了什么。(

class Animal:
def __init__(self, name, sound):
self.name = name
self.sound = sound
def change_animal(animal_1, animal_2):
animal_1 = None
animal_1 = animal_2
# or better yet,
# animal_1 = copy.deepcopy(animal_2)
# main
animal_1 = Animal('dog', 'bark')
animal_2 = Animal('duck', 'quack')
change_animal(animal_1, animal_2)
print(animal_1.name)

打印dog。我一直认为它会更改实例并打印duck

而使用这个:

def change_animal(animal_1, animal_2):
animal_1.name = animal_2.name
animal_1.sound = animal_2.sound

是否打印duck以显示实例已更改?

我想避免写任何需要我单独重新分配每个属性的东西,因为很有可能有人遗漏了一个变量,并错误地组合了更新和旧的值。

在python中,您需要返回值。当调用函数时,python正在复制animal_1对象,并在函数结束后将其销毁。如果要更改animal_1,则需要将其作为函数结果返回。

class Animal:
def __init__(self, name, sound):
self.name = name
self.sound = sound
def change_animal(animal_1, animal_2):
animal_1 = deepcopy(animal_2)
return animal_1
# main
animal_1 = Animal('dog', 'bark')
animal_2 = Animal('duck', 'quack')
animal_1 = change_animal(animal_1, animal_2)

另一个选项是在Animal类中创建函数。

class Animal:
def __init__(self, name, sound):
self.name = name
self.sound = sound
def change_animal(self, animal_2):
self.name = animal_2.name
self.sound = animal_2.sound
animal_1 = Animal('dog', 'bark')
animal_2 = Animal('duck', 'quack')
animal_1.change_animal(animal_2)

在第一个示例中,名称没有更改为duck的原因是因为被称为变量的作用域。你可以在那里阅读更多关于手续的信息,所以让我们在这里保持简单:

非正式地说,第一个函数change_animal在其中创建了一个名为animal_1的新变量。此变量在change_animal之外不可见,并且在函数结束时丢失。

您的第二个函数change_animal确实通过引用获取动物,并操纵在脚本范围内可见的对象animal_1

如果你想(出于任何原因(以某种方式保持第一个change_animal函数的风格,那么修改最少的例子可能是这样的:

class Animal:
def __init__(self, name, sound):
self.name = name
self.sound = sound
def change_animal(animal_1, animal_2):
animal_1 = None
animal_1 = animal_2
return animal_1
# or better yet,
# animal_1 = copy.deepcopy(animal_2)
# main
animal_1 = Animal('dog', 'bark')
animal_2 = Animal('duck', 'quack')
animal_1 = change_animal(animal_1, animal_2)
print(animal_1.name)

它确实如您所期望的那样打印duck

最新更新