繁体   English   中英

如何使用 class 和方法打印姓名和性别?

[英]How to print the Name and Gender by using class and methods?

我正在编写一个程序,它将呈现输入的人的姓名和性别。 程序应该询问姓名,然后询问性别,直到用户只按Enter作为姓名。 只有在按下Enter后,所有人的文本才应为 output。 我之前尝试过实现一些代码,但不幸的是我没有得到任何结果。

class Person():
    def __init__(self):
        self.name = input('Name: ')
        self.gender= input('Gender: ')

    def give_name(self):
        return self.name

    def give_gender(self):
        return self.gender

    def show_name(self):
        return self.give_name() + ' is ' + self.give_gender()

my_person = Person()
print(my_person.show_name())

最后应该 output 如下:

Name: Maya Mitermacht
Gender: female 
Name: Max Mustermann
Gender: male
Name:
Maya Mitermacht is female
Max Mustermann is male

由于输入将决定是否创建 object,因此不能由对象/类本身来自动初始化它。 您必须有办法知道输入是否为空。

因此,您应该将此委托给另一个 class 方法,从您的主程序中调用它并检查返回值。 例如,在下面的代码中,我选择在 function 中返回 True 或 False。

class Person():
    def initialize(self):
        name_entered = input('Name: ')
        if name_entered == '':
            return False
            
        gender_entered = input('Gender: ')
        if gender_entered == '':
            return False

        self.name = name_entered
        self.gender = gender_entered
        return True

    def give_name(self):
        return self.name

    def give_gender(self):
        return self.gender

    def show_name(self):
        return self.give_name() + ' is ' + self.give_gender()

persons = []
while True:
    my_person = Person()
    isCreated = my_person.initialize()
    # if it returned False, then user has entered nothing for gender or name, stop the loop
    if (not isCreated):
        break
    #other wise, person is initialized, let's add it to the list and continue
    persons.append(my_person)

for person in persons:
    print(person.show_name())

受@Pac0 的启发,我正在提交另一个答案,尽管他的答案已经足够并且效果很好!

一直困扰我的一件事只是概念问题,而不是效率或有效性。 这个想法是:如果我们想停止创建Person ,我们应该在创建下一个之前这样做,而不是在创建之后。

为此,我提出了一个使用__new__的替代方案。 也许不是最好的使用它,但它按预期工作并且具有停止在实例之间创建对象的“功能”,而不是在最后一个之后。

class Person:
    name: str
    gender: str

    def __new__(cls):
        cls.name = input('Name: ')
        if cls.name:
            cls.gender = input('Gender: ')
            return super(Person, cls).__new__(cls)
        else:
            raise ValueError("A name is required to create a Person instance")

    def __init__(self):
        self.name = Person.name
        self.gender = Person.gender

    def give_name(self):
        return self.name

    def give_gender(self):
        return self.gender

    def show_name(self):
        return self.give_name() + ' is ' + self.give_gender()


def main():
    people = []
    while True:
        try:
            new_person = Person()
        except ValueError:
            break
        else:
            people.append(new_person)

    for person in people:
        print(person.show_name())


if __name__ == "__main__":
    main()

这个想法是使用__new__来捕获输入,然后检查是否提供了名称。 如果是,继续获取性别并创建新的Person实例。 否则,提出一个例外,因为一个人需要一个名字。

用法很简单,我们可以根据需要创建任意数量的人(这里我将它们全部存储在people列表中。完成后,不提供下一个Person的名称,这将引发ValuError ,我们捕获并中断从循环中。然后,打印所有名称。


由于我已经在这里,我还将对代码提出一些一般性建议。 首先,getter 和 setter 在 Python 中并不常见,通常不鼓励使用。 因此,一个person.give_name()可以简单地被person.name交换,当它只在 class 中使用时甚至更多。 使用这个想法,我们可以将give_namegive_gendershow_name方法简化为:

class Person:
    name: str
    gender: str

    .
    .
    .

    def show_name(self):
        return self.name + ' is ' + self.gender

接下来,相信我们可以好好利用Python中的另一种“神奇”的方法,那就是__str__ 由于我们使用名称和性别来标识Person实例,并且我们希望以特定方式显示该信息,因此我们可以简单地定义Person如何表示为 string 我们使用__str__ (在类内部)来做到这一点,例如:

def __str__(self):
    return f"{self.name} is {self.gender}"

注意f-strings非常简洁且易于使用,但如果您不是粉丝,请将其替换为self.name + ' is ' + self.gender

这样,当我们在Person实例上调用str()时,它将返回相同的字符串。 如果我们直接尝试print()一个Person ,我们将得到相同的结果。 所以打印名字的循环不再需要print(person.show_name()) ,它可以简单地print(person) ——这对我来说似乎更具可读性,而且更短一点!


所以,总结一下,一切看起来像这样:

class Person:
    name: str
    gender: str

    def __new__(cls):
        cls.name = input('Name: ')
        if cls.name:
            cls.gender = input('Gender: ')
            return super(Person, cls).__new__(cls)
        else:
            raise ValueError("A name is required to create a Person instance")

    def __init__(self):
        self.name = Person.name
        self.gender = Person.gender

    def __str__(self):
        return f"{self.name} is {self.gender}"


def main():
    people = []
    while True:
        try:
            new_person = Person()
        except ValueError:
            break
        else:
            people.append(new_person)

    for person in people:
        print(person)


if __name__ == "__main__":
    main()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM