【问题标题】:How can i make __str__ or __repr__ return current class name [duplicate]我怎样才能让 __str__ 或 __repr__ 返回当前的类名 [重复]
【发布时间】:2021-11-06 02:30:30
【问题描述】:

我有这个代码:

class Employee:
    def __init__(self, name, pay, gender):
        self.name = name
        self.pay = pay
        self.gender = gender

    def add_raise(self):
        self.pay = int(self.pay*1.10)

    def __str__(self):
        if self.gender == "Female" or self.gender == "female":
            return f"{__class__.__name__} name: {self.name}, and she earns {self.pay} Pound"
        else:
            return f"{__class__.__name__} name: {self.name}, and he earns {self.pay} Pound"

    def __repr__(self):
        if self.gender == "Female" or self.gender == "female":
            return f"{__class__.__name__} name: {self.name}, and she earns {self.pay} Pound"
        else:
            return f"{__class__.__name__} name: {self.name}, and he earns {self.pay} Pound"

class Supervisor(Employee):
    def __init__(self, name, pay, gender, department):
        super().__init__(name, pay, gender)
        self.department = department

现在,当我尝试运行时

emp1 = Employee("Ron", 1000, "male")
emp10 = Supervisor("Hermoine", 3000, "female", "General")
print(emp1, emp10)

我只在开头得到“员工姓名”。如何更改它以反映“Hermoine”是一个Supervisor 而不仅仅是一个Employee,而无需重写__str____repr__ 方法?

【问题讨论】:

  • 老实说,我会在实例属性中明确“角色”,而不是尝试重用类名。在适当的__init__ 方法中添加self.role = "Employeeself.role = "Supervisor"
  • (或类属性,role = "Employee"直接在class语句命名空间中。)
  • @chepner,@U12-Forward 建议的self.__class__.__name__ 方法是__repr__ 方法的一种非常常见的模式。例如,参见collections.OrderedDictcollections.Countercollections.namedtuplecollections.ChainMapgithub.com/python/cpython/blob/main/Lib/collections/__init__.py
  • 这不是我喜欢的,尤其是strrepr 很好,无论如何它只是用作调试工具。对于__str__,我宁愿使用显式数据而不是从 code 推断出的值。
  • 好吧,很公平——但我认为有必要注意,标准库中定义这样的 __repr__ 方法可以说是规范,而将 __str__ 保留为未定义(意味着调用__str__ 将退回到 __repr__ 方法)。我也不完全确定您为什么不将类名视为显式数据——在运行时动态设置或修改类名的情况很少见。

标签: python python-3.x class python-class


【解决方案1】:

解决方案:

尝试将您的第一堂课改为:

class Employee:
    def __init__(self, name, pay, gender):
        self.name = name
        self.pay = pay
        self.gender = gender

    def add_raise(self):
        self.pay = int(self.pay*1.10)

    def __str__(self):
        if self.gender == "Female" or self.gender == "female":
            return f"{self.__class__.__name__} name: {self.name}, and she earns {self.pay} Pound"
        else:
            return f"{self.__class__.__name__} name: {self.name}, and he earns {self.pay} Pound"

    def __repr__(self):
        if self.gender == "Female" or self.gender == "female":
            return f"{self.__class__.__name__} name: {self.name}, and she earns {self.pay} Pound"
        else:
            return f"{self.__class__.__name__} name: {self.name}, and he earns {self.pay} Pound"

在所有字符串中尝试使用self.__class__.__name__ 而不是__class__.__name__

现在:

emp1 = Employee("Ron", 1000, "male")
emp10 = Supervisor("Hermoine", 3000, "female", "General")
print(emp1, emp10)

输出:

Employee name: Ron, and he earns 1000 Pound Supervisor name: Hermoine, and she earns 3000 Pound

说明:

self之所以返回实际类名,是因为它会从当前self实例中提取类名。没有self 只会得到原始父类的类名,而不是它当前所在的实际类,这就是self 如此重要的原因。

正如@MadPhysicist 提到的,它是“因为__class__ 在类执行时是词法范围的”。

【讨论】:

  • 因为__class__ 是在类执行时从词法上提取的:也就是说,它是一个硬编码的Emplpyee 参考
  • @MadPhysicist 啊,是的!将其添加到我的答案中,感谢您的建议!
猜你喜欢
  • 2012-04-29
  • 2019-06-13
  • 2013-10-09
  • 1970-01-01
  • 2014-08-11
  • 1970-01-01
  • 2019-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多