Bring namedtuple's

https://mail.python.org/pipermail/python-ideas/2014-September/029310.html

I always thought namedtuple builtin __str__ and __repr__ were very neat and I'm looking for a simple way to apply it to any classes of mine easily.

>>> 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)'

EDIT:

I initially started with a bunch of lengthy, not dynamic, hardcoded __repr__ . I don't like that. namedtuple does it fancy and automatically.

def __repr__(self):
    return 'className(attrA={attrA}, attrB={attrB})'.format(**vars(self)))

A bit hacky but this does it:

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

Example:

@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)

EDIT: (Fail-safe version)

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

If I were you, I would have created a Parent Class with the definition of __repr__ method and inherit that class in the child classes to have that behavior. To me, your solution looks like a huge hack in order to achieve very trivial thing. Below is the sample:

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

Here is the desired behavior:

>>> c = child(1, 2)
>>> repr(c)
'child(a=1, b=2)'
>>> str(c)
'child(a=1, b=2)'

when you create any class you define your own __str__ function just like you create an __init__ function

class Foo:
    def __init__(self):
        self.a="value"

    def __str__(self):
        return "a is: "+self.a

variable=Foo()
print variable

this will print: "a is: value" you can do this for any class

链接地址: http://www.djcxy.com/p/28314.html

上一篇: Python如何使用

下一篇: 带上名字的组合