0

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'
2
  • 3
    You want a.b to be 'b' and a.b.c to be 'b.c', but the string 'b' has no c attribute. Whatever underlying goal you're trying to accomplish by doing this, pick a different design. Commented Jan 21, 2021 at 8:22
  • @user2357112supportsMonica More accurately, they want a.b to print as b, which just means it is an object with a __str__ method which returns the string 'b'. That is quite feasible. Commented Jan 21, 2021 at 8:25

1 Answer 1

3

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)
Sign up to request clarification or add additional context in comments.

3 Comments

Very cool, could you explain how the getitem is working here wrt format ?
@Manakin Basically __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).
awesome thanks! also nice to see a fellow brummy on here!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.