Raphael Drechsel
Raphael Drechsel

Reputation: 35

Execute class function stored in variable on demand

I have two classes with functions:

from functools import partial

class A:
  def __init__(self, collection):
    self.collection = collection

  def filter(self, val):
    for element in self.collection:
      if element.var == val:
        return element

class B:
  def __init__(self, var):
    self.var = var

  def test(self):
    print('Element with variable ', self.var)

Now I want to have a class that can call a function on an object, fetched on the fly by another function, both stored in a variable and all executed when a certain function was called:

class C:
  def __init__(self, fetch, function):
    self.fetch = fetch
    self.function = function

  def run(self):
    global base
    # -----
    # This is the code I need
    base.fetch().function()
    # ... and currently it's completely wrong
    # -----

c = C(partial(A.filter, 5), B.test)

base = A([B(3), B(5), B(8)])

c.run()

Should print: Element with variable 5

Upvotes: 2

Views: 400

Answers (1)

Patrick Haugh
Patrick Haugh

Reputation: 61042

You should pass base into run instead of messing with global. base doesn't have a fetch method, so you have to call the fetch function you have as an attribute with base as an argument. You can then send the return value of that call to function.

You're also applying partial to A.filter slightly wrong. Positional arguments are applied in order, so partial(A.filter, 5) will try to bind 5 to self, which will throw everything off. Instead, we need to give it the name of the parameter we wish to bind 5 to.

class C:
    def __init__(self, fetch, function):
        self.fetch = fetch
        self.function = function
    def run(self, a):
        return self.function(self.fetch(a))

c = C(partial(A.filter, val=5), B.test)
c.run(A([B(3), B(5), B(8)]))
# Element with variable  5

Upvotes: 3

Related Questions