Reputation: 163
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
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