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.

Arount
  • 9,853
  • 1
  • 30
  • 43
  • 3
    Have you tried not printing? – Ignacio Vazquez-Abrams Feb 16 '18 at 09:17
  • 1
    Do I understand correctly that this should support unexpected method names? So `bas` and `ssad` are arbitrary? – Imran Feb 16 '18 at 09: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? – Jon Clements Feb 16 '18 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 – Jon Clements Feb 16 '18 at 10:08

3 Answers3

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__

Arount
  • 9,853
  • 1
  • 30
  • 43
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
Skandix
  • 1,916
  • 6
  • 27
  • 36
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'
Vikas Periyadath
  • 3,088
  • 1
  • 21
  • 33