gpt4 book ai didi

python - 如何在构造时使用参数覆盖 Python 类的 __str__ 方法?

转载 作者:行者123 更新时间:2023-11-28 16:34:17 28 4
gpt4 key购买 nike

我能做到:

class Person:
def __init__(self, firstName, lastName):
self.firstName = firstName
self.lastName = lastName

def __str__(self):
print self.firstName

bob = Person('Robert', 'Smith')
print bob
>>> Robert

但我想更通用地做而不是覆盖 __str__手动为每个类(class)。我试过使用装饰器和元类,但我很困惑。我认为应该可以做类似的事情,但我不知道如何让装饰器或元类接受一个参数并仍然创建一个正确的可实例化对象:

class strAs:

def __init__(self, prop):
self.prop = prop

def __call__(self, cls):
decoratorSelf = self
def wrapper(*args, **kwargs):
def __str__(s):
return getattr(s, decoratorSelf.prop)

c = cls(*args, **kwargs)
c.__str__ = __str__

return c
return wrapper


@strAs(prop='firstName')
class Person:
def __init__(self, firstName, lastName):
self.firstName = firstName
self.lastName = lastName

@strAs(prop='name')
class Dog:
def __init__(self, name):
self.name = name

bob = Person('Robert', 'Smith')
fido = Dog('Fido')

print bob
print fido

>>> Robert
Fido

但这失败了:

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/tmp/py6495xVN", line 33, in <module>
print bob
TypeError: __str__() takes exactly 1 argument (0 given)

我不明白为什么 __str__()没有得到 self传给了它。我注意到 bob Person 的实例类似乎缺少一些典型的对象方法,所以我尝试子类化 object像这样(并添加了两个打印语句):

class strAs(object):

def __init__(self, prop):
self.prop = prop

def __call__(self, cls):
decoratorSelf = self
def wrapper(*args, **kwargs):
print 'in wrapper'
def __newstr__(s):
print 'in newstr'
return getattr(s, decoratorSelf.prop)

c = cls(*args, **kwargs)
c.__str__ = __newstr__

return c
return wrapper


@strAs(prop='firstName')
class Person(object):
def __init__(self, firstName, lastName):
self.firstName = firstName
self.lastName = lastName

@strAs(prop='name')
class Dog(object):
def __init__(self, name):
self.name = name

bob = Person('Robert', 'Smith')
fido = Dog('Fido')

print bob
print fido

现在我用 __str__ 得到了一些输出显然被正确调用:

>>> in wrapper
in wrapper
<__main__.Person object at 0x7f179389e450>
<__main__.Dog object at 0x7f179389e510>

但它没有按应有的方式打印属性,而且似乎甚至没有使用 __newstr__函数,因为它不打印 in newstr .但是,如果我检查 bob.__str__ , 我看到它确实是 <function __newstr__ at 0x7f17951d78c0> .

我一定遗漏了一些明显的东西,但我觉得现在我已经无法理解了。 :/

最佳答案

在你的情况下,我只是让装饰器修改类。比如

class strAs:

def __init__(self, prop):
self.prop = prop

def __call__(self, cls):
prop = self.prop
def __str__(s):
return getattr(s, prop)
cls.__str__ = __str__
return cls

关于python - 如何在构造时使用参数覆盖 Python 类的 __str__ 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28623558/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com