python – 使用单例作为计数器
作者:互联网
我有一个自动化测试,它使用为文件夹创建屏幕截图的功能.此功能由多个屏幕截图实例调用.在每次测试运行时,都会创建一个新文件夹,所以我不关心计数器重置.为了反映这些屏幕截图的顺序,我必须提出可以按顺序排序的名称.这是我的解决方案:
def make_screenshot_file(file_name):
order = Counter().count
test_suites_path = _make_job_directory()
return make_writable_file(os.path.join(test_suites_path,'screenshot',file_name % order))
class Counter():
__counter_instance = None
def __init__(self):
if Counter.__counter_instance is None:
self.count = 1
Counter.__counter_instance = self
else:
Counter.__counter_instance.count += 1
self.count = Counter.__counter_instance.count
这对我来说可以.但我一直认为应该有一种更简单的方法来解决这个问题.在那儿?如果单身是唯一的方式,我的代码可以以任何方式进行优化吗?
解决方法:
你在这里要做的是模拟一个全局变量.
没有充分的理由这样做.如果您真的想要一个全局变量,请将其显式化为全局变量.
您可以创建一个简单的Counter类,每次访问它时计数增加1,然后创建它的全局实例.但正如DSM在评论中解释的那样,标准库已经在itertools.count
年免费提供了类似的东西.
所以:
import itertools
_counter = itertools.count()
def make_screenshot_file(file_name):
order = next(_counter)
test_suites_path = _make_job_directory()
return make_writable_file(os.path.join(test_suites_path,'screenshot',file_name % order))
我不确定为什么你会担心这会占用多少存储空间或时间,因为我无法设想任何可能无关紧要的程序,无论你是使用8个字节还是800个单个对象当你只做几次时,有多个或者,或者是否需要3ns或3us才能访问它.
但是如果你担心,正如你在the source中看到的那样,count是用C实现的,它的内存效率相当高,如果你不做任何花哨的事情,那么基本上只需要一个PyNumber_Add来生成每个数字,这比解释几行代码要少得多.
既然你问过,这里是如何通过使用_count类属性而不是__counter_instance类属性从根本上简化现有代码:
class Counter():
_count = 0
def count(self):
Counter._count += 1
return Counter.count
当然现在你必须使用Counter().count()而不仅仅是Counter().count – 但如果重要的话你可以用@property来解决这个问题.
值得指出的是,使用经典类而不是新式类(通过在parens中传递任何内容)是一个非常糟糕的主意,如果你想要一个经典类,你应该抛弃parens,大多数Python程序员将名称Counter与类collections.Counter相关联,并且没有理由计数不能是@classmethod或@ staticmethod ……此时这正是Andrew T.的答案.正如他所指出的那样,这比你正在做的更简单,而且不会更多或更少的Pythonic.
但实际上,所有这些并不比仅仅使_count成为模块级全局并添加模块级count()函数更好并且返回它更好.
标签:python-2-6,python,singleton 来源: https://codeday.me/bug/20190729/1568529.html