7

We have some variable, or other instance: a='?'. We have such input:

f = a(3112).bas(443).ssad(34) 

When we type

print(f)

Output should be:

3112a-443bas-34ssad

I've tried some ways to solve this and have found information about chaining, but I still have the problem. I can't return class name to the brginning of the string.

This, what I have:

class A():       

    def __getattribute__(self, item):
        print (str(item))
        return super(A, self).__getattribute__(item)    

    def __init__(self, x):
        self.x = x
        print (str(x))

    def b(self, item):
        print (str(item))        
        return self

    def c(self, item):
        print (str(item))
        return self

    def d(self, item):
        print (str(item))
        return self

A(100).b(200).c(300).d(400)

My output:

100
b
200
c
300
d
400

But I couldn't concatenate it in one string.

4
  • 3
    Have you tried not printing? Commented Feb 16, 2018 at 9:17
  • 1
    Do I understand correctly that this should support unexpected method names? So bas and ssad are arbitrary? Commented Feb 16, 2018 at 9:26
  • Is this something you need to write using chaining or an underling XY problem? eg: Do you actually want the line demonstrated as Python code, or is it something you need to parse, or is it something you could just do using string concatenation? Commented Feb 16, 2018 at 10:03
  • It seems ultimately you're after '-'.join('{}{}'.format(*el) for el in (('a', 5), ('b', 6), ('c', 35345), ('d', 666))) in some other way Commented Feb 16, 2018 at 10:08

3 Answers 3

6

Dynamic way

class A(object):

    def __init__(self, integer):
        self._strings = ['{}a'.format(integer)]


    def __getattr__(self, attrname, *args):
        def wrapper(*args, **kwargs):
            self._strings.append('{}{}'.format(args[0], attrname))
            return self

        return wrapper


    def __str__(self):
        return '-'.join(self._strings)


print(A(100).bas(200).ssad(300))

Output

100a-200bas-300ssad

But also

 print(A(100).egg(200).bacon(300).SPAM(1000))

Output

100a-200egg-300bacon-1000SPAM

Static way

class A(object):

    def __init__(self, integer):
        self._strings = ['{}a'.format(integer)]


    def bas(self, integer):
        self._strings.append('{}bas'.format(integer))
        return self

    def ssad(self, integer):
        self._strings.append('{}ssad'.format(integer))
        return self

    def __str__(self):
        return '-'.join(self._strings)


print(A(100).b(200).c(300))

Output

100a-200bas-300ssad

More about __str__

Sign up to request clarification or add additional context in comments.

4 Comments

It looks like he needs to handle arbitrary method calls. bas and ssad could be any unexpected method name.
a couple of seconds apart, but we have the same basic idea.
removed my answer as this is now clearly much better. The only comment I would have is that it seems your _dynamic_function isn't used, and so might be unnecessary here.
Oh, that's great. Thanks for solution.
5

You can override the __str__ method to define your specific output:

class A():
    def __init__(self, a, b="", c="", d=""):
        self._a = a
        self._b = b
        self._c = c
        self._d = d

    def __str__(self):
        return '{}a-{}b-{}c-{}d'.format( self.a, self.b, self.c, self.d )

    def b(self, item):
        self._b = item
        return self

    def c(self, item):
        self._c = item
        return self

    def d(self, item):
        self._d = item
        return self

f = A(100).b(200).c(300).d(400)
print(f)  # 100a-200b-300c-400d

Comments

2

Here I tried it in another way , ie, If you want to take the function name instead of manually giving it you can use inspect in python. Try this code :

import inspect


class A():
   l = []

   def __init__(self, x):
        self.x = x
        print (str(x))
        self.l.append(str(x) + "a")

    def b(self, item):
        print (str(item))
        self.l.append(str(item) + inspect.stack()[0][3])
        return self

    def c(self, item):
        print (str(item))
        self.l.append(str(item) + inspect.stack()[0][3])
        return self

    def d(self, item):
        print (str(item))
        self.l.append(str(item) + inspect.stack()[0][3])
        return self


print("-".join(A(100).b(200).c(300).d(400).l))

The o/p is like :

'100a-200b-300c-400d'

1 Comment

Thanks a lot @vikasdamodar

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.