python的新手,所以我有这个设置,我创建文件,我必须添加一个分机号码。第一个文件的扩展号为1,因为它是第一个。创建第二个文件,扩展号将增加,因此它将为2.因此每个文件都会创建,扩展号将增加。
现在,如果它是另一天,那么该分机号码将重置为1,并且如果创建新文件,它将递增。因此,每天,分机号码需要重置为1
def get_counter(date):
counter = 1
now = datetime.datetime.utcnow().strftime('%Y-%m-%d')
if date != now:
now = date
counter = 1
return counter
counter += 1
return counter
我已经设置了此功能,但它不起作用,因为now
和counter
变量将被覆盖。所以在其他地方需要这些变量。只是想知道是否有关于这个过程的工作,或者是否有一个python库可以处理这种情况。您的建议将不胜感激!
答案 0 :(得分:0)
您可以在该功能之外指定计数器并将其作为参数发送,这样您每次调用函数时都不会覆盖它,如下所示:
counter = 1
for file_to_be_writen in file_collection:
counter = get_counter(date, counter)
并保留您的功能:
def get_counter(date, counter):
now = datetime.datetime.utcnow().strftime('%Y-%m-%d')
if date == now:
counter += 1
return counter
return counter
答案 1 :(得分:0)
当您需要跨函数调用保留状态时,这是一个需要自定义对象的提示。您也可以使用全局变量,但将状态封装在对象中通常会更好。
在这里,我实现了一个可以处理所有事情的类Counter
。它有一个__next__
方法,返回下一个数字,因此调用代码只需要调用next(counter)
。它还有__iter__
方法,因此可以在for
循环中使用。
您需要提供一个函数来在创建实例时获取当前(date_getter
)时间。除了使代码更易于测试之外,这还允许您决定是否要使用utc时间,本地时间,一周的第一天,以便计数器每周重置等等。
import datetime
class TimeArrowReversedError(Exception):
pass
class Counter:
def __init__(self, date_getter):
self._date_getter = date_getter
self._current_date = date_getter()
self._current_value = 0
def _check_date(self):
current_date = self._date_getter()
if self._current_date > current_date:
message = 'Time arrow got reversed. Abandon all hope.'
raise TimeArrowReversedError(message)
if self._current_date < current_date:
self._current_date = current_date
self._current_value = 0
def __next__(self):
self._check_date()
self._current_value += 1
return self._current_value
def __iter__(self):
return self
这是我用来测试它的代码。请注意,我使用date_getter
函数实际返回我想要的任何日期。我不想等到23:59才能进行测试。相反,我告诉函数返回哪个日期(包括及时倒退)并查看计数器的行为。
current_date = datetime.date(year=2018, month=5, day=9)
get_current_date = lambda: current_date
counter = Counter(get_current_date)
n = next(counter)
assert n == 1
n = next(counter)
assert n == 2
for expected, result in zip([3, 4], counter):
assert expected == result
current_date = current_date + datetime.timedelta(days=1)
n = next(counter)
assert n == 1
n = next(counter)
assert n == 2
current_date = current_date - datetime.timedelta(days=2)
try:
n = next(counter)
except TimeArrowReversedError:
pass
else:
raise AssertionError('"TimeArrowReversedError" expected.')
这是一个更现实的方式,你可以使用这个类:
def create_counter():
return Counter(datetime.datetime.utcnow().date)
counter = create_counter()
打印前几个数字:
print(next(counter))
print(next(counter))
输出:
1
2
使用循环将数字添加到列表中的名称:
names = ['foo', 'bar']
for name, n in zip(names, counter):
print('{}_{}'.format(name, n))
输出:
foo_3
bar_4
现在我意识到Counter
是一个非常糟糕的选择,因为标准库中已经有一个完全不相关的Counter
类。但我现在想不出更好的名字,所以我会保持原样。