如果没有实现,动态实现 __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__的主要内容,如果未能解决你的问题,请参考以下文章