how to pass method name as a parameter in python c

2019-04-15 16:19发布

问题:

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)

回答1:

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']