将 namedtuple 的 __str__ 和 __repr__ 行为变为常规 类
Bring namedtuple's __str__ and __repr__ behavior to regular classes
https://mail.python.org/pipermail/python-ideas/2014-September/029310.html
我一直认为 namedtuple
内置 __str__
和 __repr__
非常简洁,我正在寻找一种简单的方法来轻松地将它应用到我的任何 类 .
>>> from collections import namedtuple
>>> A = namedtuple("A", ["foo"])
>>> print(A(foo=1))
A(foo=1)
>>> str(A(foo=1))
'A(foo=1)'
>>> repr(A(foo=1))
'A(foo=1)'
编辑:
我最初是从一堆冗长的、非动态的、硬编码的 __repr__
开始的。我不喜欢那样。 namedtuple
是否花哨且自动。
def __repr__(self):
return 'className(attrA={attrA}, attrB={attrB})'.format(**vars(self)))
有点老套,但这样做了:
from collections import namedtuple
def nice_repr(obj):
def nice_repr(self):
return repr(
namedtuple(
type(self).__name__,
vars(self)
)(**vars(self))
)
obj.__repr__ = nice_repr
return obj
示例:
@nice_repr
class A:
def __init__(self, b, c):
self.b = b
self.c = c
print(repr(A(1, 2))) # Outputs: A(c=2, b=1)
编辑:(Fail-safe 版本)
def nice_repr(obj):
""" Decorator to bring namedtuple's __repr__ behavior to regular classes. """
def nice_repr(self):
v = vars(self)
# Prevent infinite looping if `vars` happens to include `self`.
del(v['self'])
return repr(namedtuple(type(self).__name__, v)(**v))
obj.__repr__ = nice_repr
return obj
当您创建任何 class 时,您定义自己的 __str__
函数就像创建 __init__
函数一样
class Foo:
def __init__(self):
self.a="value"
def __str__(self):
return "a is: "+self.a
variable=Foo()
print variable
这将打印:"a is: value"
您可以对任何 class
执行此操作
如果我是你,我会用 __repr__
方法的定义创建一个父 Class 并在子 class 中继承那个 class 有那种行为。对我来说, 看起来像是为了实现非常微不足道的事情而进行的巨大黑客攻击。下面是示例:
class BaseClass:
# logic can be used with in `__repr__` itself.
# creating separate function to make it more clear
def _get_formatted_string(self):
return '{class_name}({params})'.format(
class_name=self.__class__.__name__,
params=', '.join('{}={}'.format(k, v) for k, v in vars(self).items()))
def __repr__(self):
return self._get_formatted_string()
class child(BaseClass):
def __init__(self, a, b):
self.a = a
self.b = b
这是期望的行为:
>>> c = child(1, 2)
>>> repr(c)
'child(a=1, b=2)'
>>> str(c)
'child(a=1, b=2)'
typing.NamedTuple新颖优雅。 collections.namedtuple.
的更好版本
from typing import NamedTuple
class Employee(NamedTuple):
name: str
id: int
与
基本相同
Employee = collections.namedtuple('Employee', ['name', 'id'])
这个问题的一个更高级的例子
from typing imoprt NamedTuple
class Employee(NamedTuple):
"""Represents an employee."""
name: str
id: int = 3
def __repr__(self) -> str:
return f'<Employee {self.name}, id={self.id}>'
见https://docs.python.org/3/library/typing.html#typing.NamedTuple
https://mail.python.org/pipermail/python-ideas/2014-September/029310.html
我一直认为 namedtuple
内置 __str__
和 __repr__
非常简洁,我正在寻找一种简单的方法来轻松地将它应用到我的任何 类 .
>>> from collections import namedtuple
>>> A = namedtuple("A", ["foo"])
>>> print(A(foo=1))
A(foo=1)
>>> str(A(foo=1))
'A(foo=1)'
>>> repr(A(foo=1))
'A(foo=1)'
编辑:
我最初是从一堆冗长的、非动态的、硬编码的 __repr__
开始的。我不喜欢那样。 namedtuple
是否花哨且自动。
def __repr__(self):
return 'className(attrA={attrA}, attrB={attrB})'.format(**vars(self)))
有点老套,但这样做了:
from collections import namedtuple
def nice_repr(obj):
def nice_repr(self):
return repr(
namedtuple(
type(self).__name__,
vars(self)
)(**vars(self))
)
obj.__repr__ = nice_repr
return obj
示例:
@nice_repr
class A:
def __init__(self, b, c):
self.b = b
self.c = c
print(repr(A(1, 2))) # Outputs: A(c=2, b=1)
编辑:(Fail-safe 版本)
def nice_repr(obj):
""" Decorator to bring namedtuple's __repr__ behavior to regular classes. """
def nice_repr(self):
v = vars(self)
# Prevent infinite looping if `vars` happens to include `self`.
del(v['self'])
return repr(namedtuple(type(self).__name__, v)(**v))
obj.__repr__ = nice_repr
return obj
当您创建任何 class 时,您定义自己的 __str__
函数就像创建 __init__
函数一样
class Foo:
def __init__(self):
self.a="value"
def __str__(self):
return "a is: "+self.a
variable=Foo()
print variable
这将打印:"a is: value" 您可以对任何 class
执行此操作如果我是你,我会用 __repr__
方法的定义创建一个父 Class 并在子 class 中继承那个 class 有那种行为。对我来说,
class BaseClass:
# logic can be used with in `__repr__` itself.
# creating separate function to make it more clear
def _get_formatted_string(self):
return '{class_name}({params})'.format(
class_name=self.__class__.__name__,
params=', '.join('{}={}'.format(k, v) for k, v in vars(self).items()))
def __repr__(self):
return self._get_formatted_string()
class child(BaseClass):
def __init__(self, a, b):
self.a = a
self.b = b
这是期望的行为:
>>> c = child(1, 2)
>>> repr(c)
'child(a=1, b=2)'
>>> str(c)
'child(a=1, b=2)'
typing.NamedTuple新颖优雅。 collections.namedtuple.
的更好版本from typing import NamedTuple
class Employee(NamedTuple):
name: str
id: int
与
基本相同Employee = collections.namedtuple('Employee', ['name', 'id'])
这个问题的一个更高级的例子
from typing imoprt NamedTuple
class Employee(NamedTuple):
"""Represents an employee."""
name: str
id: int = 3
def __repr__(self) -> str:
return f'<Employee {self.name}, id={self.id}>'
见https://docs.python.org/3/library/typing.html#typing.NamedTuple