使用循环创建不同的 Python 对象

Creating Distinct Python Objects Using Loop

我有以下 Python 代码:

from names import get_first_name, get_last_name

class Person(object):
    def __init__(self, first_name=get_first_name(), last_name=get_last_name()):
        self.first_name = first_name
        self.last_name = last_name


def make_group_of_people(num_people):
    people = []
    num = 0
    while num < num_people:
        person = Person(
            first_name=get_first_name(),
            last_name=get_last_name(),
        )
        people.append(person)
        num += 1
    return people


group = make_group_of_people(3)

for person in group:
    print(f"***NEW PERSON {group.index(person)}***")
    print(person.first_name)
    print(person.last_name)

打印出不同的名字,像这样:

***NEW PERSON 0***
Christine
Thomas
***NEW PERSON 1***
Orlando
Goff
***NEW PERSON 2***
William
Bedwell

我不明白的是,当我 运行 这个非常相似的 Python 代码时:

from names import get_first_name, get_last_name

class Person():
    def __init__(self, first_name=get_first_name(), last_name=get_last_name()):
        self.first_name = first_name
        self.last_name = last_name
 

def make_group_of_people_2(num_people):
    people = []
    num = 0
    while num < num_people:
        person = Person() ### HERE'S WHAT'S DIFFERENT ###
        people.append(person)
        num += 1
    return people


same_named_group = make_group_of_people_2(3)

for person in same_named_group:
    print(f"***NEW PERSON {same_named_group.index(person)}***")
    print(person.first_name)
    print(person.last_name)

我得到这个输出,表明每个对象都有名字和姓氏:

***NEW PERSON 0***
Michael
Baylock
***NEW PERSON 1***
Michael
Baylock
***NEW PERSON 2***
Michael
Baylock

令我困惑的是,我希望这两段代码打印出不同的名称,因为在这两种情况下,Personfirst_namelast_name 的默认值class 是 names package 的随机名称生成器函数的结果,但显然不是这样。

我看过 this question,但它并不能完全回答我所看到的。

知道为什么会这样吗?这在所有 OOP 语言中是否一致?

问题是你的构造函数:

class Person(object):
    def __init__(self, first_name=get_first_name(), last_name=get_last_name()):
        self.first_name = first_name
        self.last_name = last_name

在定义函数时(即一次)评估默认参数值,而不是每次调用函数时。 (如果你坚持一些登录 get_first_name() 你会看到它只在你的代码的版本 2 中被调用一次。)如果你希望默认值每次都不同,请执行:

class Person:
    def __init__(self, first_name=None, last_name=None):
        self.first_name = first_name or get_first_name()
        self.last_name = last_name or get_last_name()

这样函数调用 get_first_name()get_last_name() 每次调用函数时都没有相应的参数。

您已经为名字和姓氏参数定义了默认值。默认值意味着如果你不指定它,它会被自动选中。请参阅以下代码片段:

from names import get_first_name

default = get_first_name()
print(default)

所以当你写的时候:

person = Person()

将选择默认值。