Pythonic创建动态类方法的方法

时间:2015-11-03 18:16:43

标签: python function class methods

我想知道以下策略是否是在方法中创建动态函数的正确/ pythonic方式。目标是有一个类可以根据FUN()定义的复杂模型计算一个值,但我希望能够在脚本中更改该模型而不重写它,或创建一堆不同类型的类(因为这个函数是我期望改变的唯一的东西)。

我还读到对这个question的回应,我的结构方式可能会变慢?我打算在模拟时调用setupFunction() 1至3次(更改模型)并调用FUN数千次。

...伪代码

class MyClass:

  def __init__(self, model = 'A'):
    self.setupFunction(model)
    # Other Class Stuff...

  def setupFunction(self, _model):
    if _model == 'A':
      def myFunc(x):
        # Do something with x, store in result
        return result
    else:
      def myFunc(x):
        # Do something different with x
        return result
    self.FUN = myFunc

  # Other Class Methods... some of which may call upon self.FUN


Model1 = MyClass('A')
Model2 = MyClass('B')
print(Model1.FUN(10))
print(Model2.FUN(10))

我做了一些小的测试,上面似乎没有打破第一眼。我知道我也可以通过执行以下操作来做类似的事情,但是它必须在每次调用FUN()时测试模型,最后我会有许多不同的模型案例:

class MyClass():

  def __init__(self, model = 'A'):

  def FUN(self, x):
    if self.model == 'A':
      # result = Stuff
    else:
      # result = Other Stuff
    return result

仍然是python的新手,所以感谢任何反馈!

2 个答案:

答案 0 :(得分:1)

不确定我是否理解你的问题...... 这样的事情怎么样?

class MyClass():

    model_func = {'A' : funca, 'B' : funcb}

    def __init__(self, model):
        self.func = self.model_func[model]

    def funca():
        pass

    def funcb():
        pass

a = MyClass('A')
a.func()

b = MyClass('B')
b.func()

其他选项可能是这样的(更好地分离关注点):

class Base(object):

    def __new__(cls, category, *arguments, **keywords):
        for subclass in Base.__subclasses__():
            if subclass.category == category:
                return super(cls, subclass).__new__(subclass, *arguments, **keywords)
        raise Exception, 'Category not supported!'

class ChildA(Base):
    category = 'A'

    def __init__(self, *arguments, **keywords):
        print 'Init for Category A', arguments, keywords

    def func(self):
        print 'func for Category A'


class ChildB(Base):
    category = 'B'

    def func(self):
        print 'func for Category B'

if __name__ == '__main__':
    a = Base('A')
    a.func()
    print type(a)
    b = Base('B')
    b.func()
    print type(b)

答案 1 :(得分:1)

您可以使用__new__来返回不同的子类:

class MyClass():
    def __new__(self, model):
        cls = {'A': ClassA, 'B': ClassB}[model]
        return object.__new__(cls)

class ClassA(MyClass):
    def func():
        print("This is ClassA.func")

class ClassB(MyClass):
    def func():
        print("This is ClassB.func")

a = MyClass('A')
a.func()

b = MyClass('B')
b.func()