Python:如何在Class中动态分配函数名称

时间:2016-09-29 05:14:38

标签: python

我有一个关于如何在Class中动态分配函数名的问题。

例如:

If a class wants to be used for "for...in" loop, similar to a list
or a tuple, you must implement an __iter__ () method

python2.x will use __iter__() and next(),
python3.x need to use __iter__() and __next__()

代码:

样品的纤维蛋白数量在10

以内
class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    if sys.version_info[0] == 2:
        iter_n = 'next'  #if python version is 2.x
    else:
        iter_n = '__next__'  #if python version is 3.x

    print('iter_n value is ', iter_n)

    #for py2 I want to replace "iter_n" to "next" dynamically
    #for py3 I want to replace "iter_n" to "__next__" dynamically

    def iter_n(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > 10:
            raise StopIteration();
        return self.a

测试:

for i in Fib():
    print(i)

预期结果应为:

('iter_n value is ', 'next')
1
1
2
3
5
8

实际结果:

('iter_n value is ', 'next')
Traceback (most recent call last):
......
TypeError: iter() returned non-iterator of type 'Fib'

代码将能够获得正确的结果

  • for python 2,如果我将def iter_n(self)替换为def next(self)
  • for python 3,如果我将def iter_n(self)替换为def __next__(self)

问题:

我应该如何动态地将next__next__加入iter_n

3 个答案:

答案 0 :(得分:5)

我认为不需要动态创建此方法。 只需实施两者;更清晰,更容易。并且您的代码将兼容Python 2/3,而无需if语句。

class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def iter_n(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > 10:
            raise StopIteration();
        return self.a

    def next(self):
        return self.iter_n()

    def __next__(self):
        return self.iter_n()


if __name__ == '__main__':
    for i in Fib():
        print(i)

答案 1 :(得分:1)

同意只是实施两者可能是最好的,但这样的事情似乎符合你的意图:

    def iter_n(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > 10:
            raise StopIteration();
        return self.a

    if sys.version_info[0] == 2:
        next = iter_n
    else:
        __next__ = iter_n
    del iter_n

一旦将原始iter_n分配给相应的属性,上述内容就会删除。据推测,如果你正在进行这项工作,你也会想要进行清理。

答案 2 :(得分:-1)

在python中有一种方法可以调用一个函数,方法,通过使用getattr(from,'name of property to call')来获取任何元素。

下面是

的示例:

class A():
    def s(self):
            print "s fun"
    def d(self):
            print "a fun"
    def run(self):
            print "in run"

def main():
    print "in main"
    classA = A()
    func_list = ['s','d','run']
    for i in func_list:
            func = getattr(classA,i)
            func()

main()

尝试使用它来动态调用函数。