【问题标题】:Pythonic way to create dynamic class methods创建动态类方法的 Pythonic 方式
【发布时间】:2015-11-03 18:16:43
【问题描述】:

我想知道以下策略是否是在方法中创建动态函数的正确/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 还是很陌生,所以感谢任何反馈!

【问题讨论】:

  • 当然,这很好。函数和扩展方法是一流的对象,因此您可以动态地将它们分配给您的心脏内容。这是否使您的代码更易于维护或只是更混乱,这取决于您。但表面上这很好。
  • 我投票结束这个问题,因为它应该在 Stack Exchange 代码审查网站上。

标签: python function class methods


【解决方案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)

【讨论】:

  • 我认为这最终会成为最好的解决方案。谢谢!
  • 得到NameError: name 'funca' is not defined :-/
  • 只需颠倒funcafuncb的顺序即可。将主题放在model_func = {'A' : funca, 'B' : funcb}之前。
【解决方案2】:

您可以使用__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()

【讨论】:

  • 感谢您的回复!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-05
  • 2013-09-02
  • 1970-01-01
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 2020-10-19
相关资源
最近更新 更多