如果没有实现,动态实现 __str__

Posted

技术标签:

【中文标题】如果没有实现,动态实现 __str__【英文标题】:Dynamically implement __str__ if not implemented 【发布时间】:2020-08-09 03:45:14 【问题描述】:

我正在尝试编写一个函数 strFix,它将一个类对象作为参数,并检查该类是否具有 str() 方法,如果没有,将自动添加一个,打印一行中的所有成员变量,例如:打印边数、边列表和三角形面积。

但是,在调用strFix(triangle) 之后,我得到了一个返回的三角形对象而不是打印它?

def constructor(self, arg):
    self.no_of_sides = arg


def setSidesT(self, x, y, z):
    self.x = x
    self.y = y
    self.z = z
    self.listattr = [x, y, z]


def createSubClass(self):

    self = type(
        "Triangle",  # subclass name
        (Polygon,),  # super class(es)
        
            "listattr": [],  # new attributes and functions/methods
            "setSides": setSidesT,
            "findArea": (lambda obj: (obj.x + obj.y + obj.z) / 2),
            "getTriangleSides": (lambda x: print(x.listattr)),
        ,
    )
    return self


Polygon = type(
    "Polygon",
    (object,),
    
        "no_of_sides": 0,
        "__init__": constructor,
        "getSides": (lambda obj: obj.no_of_sides),
    ,
)


def Tprinter(self):
    return str(self.no_of_sides, self.getTriangleSides, self.findArea)


def strFix(self):
    if not type(self).__dict__.get("__str__"):
        setattr(self, "__str__", Tprinter)


triangle = createSubClass(Polygon)(3)
triangle.setSides(4, 5, 6)
triangle.getTriangleSides()
strFix(triangle)
print(triangle.findArea())
print(triangle)

【问题讨论】:

为什么?使用基类或混合类会更清楚。 除非您将匿名类型作为函数参数传递,否则请使用 class 语句而不是调用 type。这类似于在定义命名函数时首选 def 而不是 lambda 表达式。 @AKX 我理解,但它需要将类实现为元类,并且还需要实现 strfix 函数 这段代码中没有元类。元类是type子类,而不是type 的实例。 __str__ 方法需要进入类,不是类的实例。 【参考方案1】:

您应该只使用一个类体和一个带有默认 __str__ 的常规超类 - 同时这是正常的做法,并且可以做您想做的事情。

也就是说,您的 strFix 函数在 instance 上插入了一个 __str__ 方法,这是行不通的 - 您必须在类本身上设置 __str__

而且,当= 足够时,无需使用setattr

def strFix(instance):
    cls = instance.__class__
    if "__str__" not in cls.__dict__:
        cls.__str__ = Tprinter

【讨论】:

这里我们修改的是实例的str方法,而不是对象的方法对吧? “一个实例”和“一个对象”的意思完全一样。代码 sn-p 修改 class 中的方法(与实例的 type 相同)。 Python 查看对象的类以检查诸如__str__ 之类的魔术方法

以上是关于如果没有实现,动态实现 __str__的主要内容,如果未能解决你的问题,请参考以下文章

如果你实现 __getattribute__ 有没有办法访问形式参数

4-19 面向对象 的内置方法

Python中__str__和__repr__的区别

廖雪峰老师——Python进阶( 定制类 )

python中 __str__和__repr__

Spring09_动态代理