June2017
June2017

Reputation: 179

how to pass method name as a parameter in python class

This is my code, my intention is to pass the method name as a parameter when I initialize the object and I want to run the method 'num' (second argument) of times. Basically get n number of results (as mentioned in 2nd argument).

 class Foo(object):
     faker = Faker()

     def __init__(self,  custom_method, num=1):
         self.values = []
         self.custom_method = custom_method
         self.num = num
         for x in self.num:
             self.custom_method = self.values.append(custom_method)


    def random_first_name(self):
        self.custom_method = self.faker.first.name()
        return self.custom_method

    def random_phone(self):
        self.custom_method = self.faker.random.phone()
        return self.custom_method

    b = Foo(random_first_name, 1)
    c = Foo(random_phone,2)

Upvotes: 2

Views: 5288

Answers (1)

keepAlive
keepAlive

Reputation: 6665

I guess that you may want to use the function getattr.

class Foo(object):
    faker = Faker()

    def __init__(self, custom_method, num=1):
        self.custom_method = custom_method
        self.num = num

    @property # Briefly, the property decorator makes the job of calling the callable for you. I.e. There is no need to do self.method(), self.method is enough.
    def random_first_name(self):
        return self.faker.first.name()

    @property
    def random_phone(self):
        return self.faker.random.phone()

    def call_method_num_times(self):
        return [getattr(self, self.custom_method)\
                for _ in range(self.num)]

I cannot instantiate this class, but this could be used as follows:

>>> foo1 = Foo('random_first_name', 1)
>>> foo1.call_method_num_times()
['John']

>>> foo2 = Foo('random_phone', 2)
>>> foo2.call_method_num_times()
['0123456789', '9876543210']


To (even more) reorganize your class in a (subjectively) better fashion, I would do

class Foo(object):

    def __init__(self):
        self.faker = Faker()

    @property
    def random_first_name(self):
        return self.faker.first.name()

    @property
    def random_phone(self):
        return self.faker.random.phone()

    def call_method_num_times(self, custom_method, num=1):
        return [getattr(self, custom_method)\
                for _ in range(num)]

Thus allowing you for instantiating Foo only once

>>> foo = Foo()
>>> foo.call_method_num_times('random_first_name')
['John']
>>> foo.call_method_num_times('random_phone', 2)
['0123456789', '9876543210']


If you are not comfortable with the use of the python native property descriptor, you can keep your two methods as explicite ones. In this case, you would define the class Foo as follows

class Foo(object):

    def __init__(self):
        self.faker = Faker()

    def random_first_name(self):
        return self.faker.first.name()

    def random_phone(self):
        return self.faker.random.phone()

    def call_method_num_times(self, custom_method, num=1):
        return [getattr(self, custom_method)()\
                for _ in range(num)]

Which would change nothing in ways of using Foo

>>> foo = Foo()
>>> foo.call_method_num_times('random_first_name')
['John']
>>> foo.call_method_num_times('random_phone', 2)
['0123456789', '9876543210']

Upvotes: 3

Related Questions