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'
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)
__getitem__ is the method which gets called when you access a[i], so it returns a new magic object with the string a[i] where the !r part converts i to its "repr" string (so you get quotes around strings, for example).
a.bto be'b'anda.b.cto be'b.c', but the string'b'has nocattribute. Whatever underlying goal you're trying to accomplish by doing this, pick a different design.a.bto print asb, which just means it is an object with a__str__method which returns the string'b'. That is quite feasible.