我在同一个类中实现了一些逻辑进程。
类实例为每个进程获取一个生成器,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)
典型流程为discovery
,authentication
,watchdog
等。
如何以合理的方式命名定义生成器和包含生成器对象的属性的函数?
最后只是为了踢,同名的名字会疯了,对吗?
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
答案 0 :(得分:4)
您可以使用您自己设计的某种形式,使用函数的名称自动创建包含生成器的成员。例如,在我的约定中,所有生成器都将由名为<function_name>_gen
的成员包含。
我会将函数名称称为其责任:discovery
,authentication
和watchdog
是好名字。因此,您只需要一种自动设置的方式:self.discovery_gen
,self.authentication_gen
和self.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)