Python生成器函数/对象命名约定

时间:2014-11-05 10:42:50

标签: python naming-conventions generator naming lightweight-processes

我在同一个类中实现了一些逻辑进程。 类实例为每个进程获取一个生成器,run()推进所述生成器。在我的情况下,发电机不会结束。

如何在下面的代码中调用 foo_function foo_object

class C(threading.Thread):
    def foo_function(self):
        """ generator *function*,
            logical process foo """
        while True:
            # some state checks
            if self.some_attr:
                # side-effects here
                pass
            yield

    def __init__(self):
        # generator *object*
        # i.e. process instance
        self.foo_object = self.foo_function()  # <- here

    def run(self):
        while True:
            next(self.foo_object)
            next(self.another_object)
            if xxx:
                next(self.yet_another_object)

典型流程为discoveryauthenticationwatchdog等。

如何以合理的方式命名定义生成器和包含生成器对象的属性的函数?

最后只是为了踢,同名的名字会疯了,对吗?

class C:
    def foo(self):
        yield 1; yield 2
    def __init__(self):
        self.foo = self.foo()

c = C()            
type(C.foo) is function
type(c.foo) is generator

3 个答案:

答案 0 :(得分:4)

您可以使用您自己设计的某种形式,使用函数的名称自动创建包含生成器的成员。例如,在我的约定中,所有生成器都将由名为<function_name>_gen的成员包含。

我会将函数名称称为其责任:discoveryauthenticationwatchdog是好名字。因此,您只需要一种自动设置的方式:self.discovery_genself.authentication_genself.watchdog_gen

代码示例:

class C:

    def discovery(self):
        yield 1; yield 2

    # Register all the functions for wich you want to have a generator
    # object.
    REGISTERED_GEN_FUNCTIONS = [discovery]

    def __init__(self):

        for func in self.REGISTERED_GEN_FUNCTIONS:
            name = func.__name__
            # All generators objects will be called <function_name>_gen.
            setattr(self, "{0}_gen".format(name), getattr(self, name)())

a = C()
for i in a.discovery_gen:
    print(i)

输出继电器

>>> 1
>>> 2 

答案 1 :(得分:3)

如果仅在run方法内访问生成器,则可以执行以下操作:

class C:
    def a_process(self):
        while True: yield

    def another_process(self):
        while True: yield

    def run(self):
        # Use itertools.izip in python 2
        for _ in zip(a_process(), another_process()):
            pass

在这里,zip和for循环将自动创建和推进生成器。这样,您就不需要跟踪它们了。

如果您需要访问run方法之外的生成器,您可以创建一个有序的生成器字典(如果生成器需要按照定义的顺序前进):

from collections import OrderedDict

class C:
    # Processes here

    def __init__(self):
        self.generators = OrderedDict()
        for gn in ('a_process', 'another_process'):
            self.generators[gn] = getattr(self, gn)()

    def run(self):
        while True:
            for g in self.generators.values():
                next(g)

答案 2 :(得分:0)

仅解决标题“ python generator function命名约定”。

我个人喜欢将生成器函数命名为“ yield_items”。代码自然地读取,关键字yield表示它输出一个生成器对象。

def yield_squares(iter_max=10):
    for i in range(iter_max):
        yield i**2

squares = yield_squares()
for square in squares:
    print(square)