Allen
Allen

Reputation: 163

How to transfer an object's methods to string in Python?

How to make an object to return string that anything after the object name?

a = AnyMethodToString()
print(a.b.c[1].d["e"].f)
=> 'b.c[1].d["e"].f'

Upvotes: 0

Views: 100

Answers (1)

kaya3
kaya3

Reputation: 51093

Interesting challenge, this is possible by writing a class with __getattr__ and __getitem__ methods. To keep things simple, I made the variable s part of a closure instead of an attribute, otherwise self.s could ambiguously refer to either the string or the __getattr__ method.

For bonus points, the __call__ method allows you to put method calls in there, too.

def magic(s=''):
    class Magic:
        def __str__(self):
            return s
        def __repr__(self):
            return s
        def __getattr__(self, i):
            return magic('{0}.{1}'.format(s, i).lstrip('.'))
        def __getitem__(self, i):
            return magic('{0}[{1!r}]'.format(s, i))
        def __call__(self, *args, **kwargs):
            a = [repr(x) for x in args]
            a += ['{0}={1!r}'.format(k, x) for k, x in kwargs.items()]
            return magic('{0}({1})'.format(s, ', '.join(a)))
    return Magic()

Usage:

>>> a = magic('a')
>>> a.b
a.b
>>> a.b.c
a.b.c
>>> a.b.c[1].d["e"].f
a.b.c[1].d['e'].f
>>> a.foo('bar', baz=4)
a.foo('bar', baz=4)

Or without the a. part:

>>> a = magic()
>>> a.b
b
>>> a.b.c
b.c
>>> a.b.c[1].d["e"].f
b.c[1].d['e'].f
>>> a.foo('bar', baz=4)
foo('bar', baz=4)

Upvotes: 3

Related Questions