-1

Say I have a class Bucket and a function do_thing (this is a hugely simplified example). I want to pass an argument to do_thing that will create an instance of Bucket and carry out the specified method on that Bucket object.

Class Bucket:
    __init__(self, volume):
        ...
    def fill(self):
        ...
    def empty(self):
        ...

def do_thing(method, vol):
    A = Bucket(vol)
    A.method()

This doesn't work, as obviously if I try do_thing("fill", 200), it raises AttributeError: Bucket instance has no attribute 'method'. So how can I call the specific method (fill in this case?)

binaryfunt
  • 6,401
  • 5
  • 37
  • 59
  • 1
    `getattr(A, method)()`? Python won't magically substitute the attribute name `method` with the value of the unrelated parameter `method`. See also http://stackoverflow.com/q/3521715/3001761 – jonrsharpe Nov 04 '15 at 11:23
  • @jonrsharpe Cool. My Googling didn't return that particular question, but hopefully from now on it would via this one – binaryfunt Nov 04 '15 at 12:03

1 Answers1

0

Well, the error says it all. Bucket doesn't have a method called 'method' and in fact, you haven't code one, you just have 'fill' and 'empty'.

Now you said you call that function with do_thing(fill, 200).

What exactly is the argument 'fill'? If the code was really this, python will fail before to get to the AttributeError as 'fill' is an undefined varible

NameError: name 'fill' is not defined

You could pass the name of the method you want to use as string. In this case you need this:

def do_thing(method, vol):
    A = Bucket(vol)
    getattr(A, method)()

do_thing('fill', 200)

However, I would suggest you to carefully think about what you want to do. This is not a very clean code. You should ask yourself if your really need to go down this path.

Dan Niero
  • 743
  • 4
  • 18