在Python上下文相关的方法 - 我究竟做错了什么?(Context dependent meth

2019-08-21 18:06发布

我想创建一个类,其方法F依赖于类的对象被创建的“模式”。

下面的代码不工作,但希望它可以让你的什么,我试图做一个想法。 我的想法是在我定义设置每种模式(在这种情况下,函数或方法分配给self.f字典来,这样,而不是使用很多,如果elif的语句在init函数我刚刚分配正确的价值观使用字典。

class A(object):
    _methods_dict={
            'a':A.f1,
            'b':A.f2
            }    

    def __init__(self,mode = 'a'):
        self.f = _methods_dict[mode]


    def f1(self,x):
        return x

    def f2(self,x):
        return x**2

我不明白为什么这不工作,你会怎么解决这个问题? 也有更好的(和更Python)接近得到同样的功能呢?

Answer 1:

商店的两个函数的名称 ,然后使用getattr()检索绑定的方法在__init__

class A(object):
    _methods_dict = {
        'a': 'f1',
        'b': 'f2'
    }    

    def __init__(self, mode='a'):
        self.f = getattr(self, self._methods_dict[mode])

    def f1(self, x):
        return x

    def f2(self, x):
        return x ** 2

或者,只是代理的方法:

class A(object):
    _methods_dict = {
        'a': 'f1',
        'b': 'f2'
    }

    def __init__(self,mode = 'a'):
        self._mode = mode

    @property
    def f(self):
        return getattr(self, self._methods_dict[self._mode])

    def f1(self, x):
        return x

    def f2(self, x):
        return x ** 2

f属性只是返回当前模式的正确绑定的方法。 使用属性简化调用签名处理,并为用户提供了实际的方法来反思,如果他们愿意的话。

任一方法具有相同的最终结果:

>>> a1 = A()
>>> a2 = A('b')
>>> a1.f(10)
10
>>> a2.f(10)
100

不同之处在于什么是存储在实例中,第一种方法商店绑定方法:

>>> vars(a1)
{'f': <bound method A.f1 of <__main__.A object at 0x10aa1ec50>>}
>>> vars(a2)
{'f': <bound method A.f2 of <__main__.A object at 0x10aa1ed50>>}

与在另一方的方法:

>>> vars(a1)
{'_mode': 'a'}
>>> vars(a2)
{'_mode': 'b'}

这似乎不是太大的差别,但后一种方法创建一个可腌制,没有问题的深复制实例。



Answer 2:

你可以只让两个独立的类:

class Base(object):
    # place here all attributes shared in common among the Modes
    pass

class ModeA(Base):
    def f(self, x):
        return x

class ModeB(Base):
    def f(self, x):
        return x**2

def make_mode(mode, *args, **kwargs):
    mode_dict = {'a':ModeA, 'b':ModeB}
    return mode_dict[mode](*args, **kwargs)

a = make_mode('a')
print(a.f(10))
# 10

b = make_mode('b')
print(b.f(10))
# 100


Answer 3:

要回答你的第一个问题(“为什么这不工作”):类对象“A”只被创建和绑定到模块的名称为“A”全班语句后(是的,“类”是一个可执行语句)块已经结束,所以你不能指既没有名称或该块内的类对象本身。



文章来源: Context dependent method in Python - what am I doing wrong?