[英]Use __str__ of each instance attribute for a class's __str__
Is there a way in Python 3 to recursively call private member variables unique __str__
functions programmatically? 有没有办法在Python 3中以编程方式递归调用私有成员变量
__str__
函数? Something like: 就像是:
class A:
def __str__(self):
return "A"
class B:
def __str__(self):
return "B"
class C:
def __init__(self):
self._A = A()
self._B = B()
def __str__(self):
for var in vars(self):
return str(var)
When calling the individual private members, it works fine. 在呼叫个人私人会员时,它运作正常。 Would like a method to do it dynamically however.
想要一种动态地做它的方法。
Thanks so much. 非常感谢。
The vars
function returns a dictionary where the keys are the variable names (as strings) and the values are the values of the variable. vars
函数返回一个字典,其中键是变量名(作为字符串),值是变量的值。 So iterating over the values should work. 所以迭代这些值应该有效。
class A:
def __str__(self):
return "A"
class B:
def __str__(self):
return "B"
class C:
def __init__(self):
self._A = A()
self._B = B()
def __str__(self):
output = ""
for _,var in vars(self).items(): #Iterate over the values
output += str(var) #Use the str() function here to make the object return its string form
return output #Need to return instead of print since that is what the __str__() function should do
You can add some kind of separator (like a \\n
) between the values if you want. 如果需要,可以在值之间添加某种分隔符(如
\\n
)。 Just replace str(var)
with str(var) + "\\n"
. 只需用
str(var) + "\\n"
替换str(var)
。
You can also use the dictionary keys; 你也可以使用字典键;
vars()
is self.__dict__
: vars()
是self.__dict__
:
>>> class A:
... def __str__(self):
... return self.__class__.__name__
...
>>> class B:
... def __str__(self):
... return self.__class__.__name__
...
>>> str(A())
'A'
>>> repr(A()) # "long-form" the hex-string is id()
'<__main__.A object at 0x10f65a908>'
>>> class C:
... def __init__(self):
... self.A = A()
... self.B = B()
... def __str__(self):
... return '\n'.join(self.__dict__)
...
>>> C()
<__main__.C object at 0x10f65aa58>
>>> print(C()) # Uses str(C())
A
B
vars(self)
is effectively self
. vars(self)
是有效的self
。 In turn, self.__dict__
is a dict
used to store an object's (writable) attributes. 反过来,
self.__dict__
是一个用于存储对象(可写)属性的dict
。
>>> C().__dict__
{'A': <__main__.A object at 0x10f65aa90>, 'B': <__main__.B object at 0x10f65aac8>}
The signature is '\\n'.join(iterable)
, and when you iterate over a dictionary, you iterate over its keys, which suffices in this case. 签名是
'\\n'.join(iterable)
,当你遍历字典时,你迭代它的键,在这种情况下就足够了。
I'm not totally sure if (Python 3.7+) dataclasses are an easier solution here. 我不完全确定(Python 3.7+)数据类是否是一个更简单的解决方案。 That's because they automatically implement a
__repr__()
but not a __str__()
as far as I can tell: 那是因为他们自动实现
__repr__()
而不是__str__()
,据我所知:
>>> from dataclasses import dataclass
>>>
>>> @dataclass
... class C:
... _A: object = A()
... _B: object = B()
...
>>> c = C() # still uses repr() for each field
>>> str(c)
'C(_A=<__main__.A object at 0x10f373828>, _B=<__main__.B object at 0x10f373940>)'
In other words, you'd need to replace A.__str__
with A.__repr__
(same for B
, which is maybe not something you want to do in the first place with regards to those two classes.) 换句话说,你需要用
A.__str__
替换A.__str__
A.__repr__
(对于B
来说也是如此,对于这两个类,这可能不是你想要做的事情。)
Are you sure you shouldn't be using __repr__
? 你确定你不应该使用
__repr__
吗?
Anyway, here's an example using attrs
, beacuse I'm stuck on Python 3.5. 无论如何,这是一个使用
attrs
的例子,因为我坚持使用Python 3.5。 With dataclasses
it will work in a similar manner. 使用
dataclasses
,它将以类似的方式工作。
import attr
class A:
def __str__(self):
return 'A'
class B:
def __str__(self):
return 'B'
@attr.s
class C:
a = attr.ib(default=attr.Factory(A))
b = attr.ib(default=attr.Factory(B))
if __name__ == '__main__':
c = C()
print(c) # __str__ defaults to __repr__
def __str__(self):
bits = ['<C']
for a in self.__attrs_attrs__:
bits.append(' %s=%s' % (a.name, getattr(self, a.name)))
bits.append('>')
return ''.join(bits)
C.__str__ = __str__
print(c) # custom __str__
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.