如果不同的一天将计数器重置为零 - Python

时间:2018-05-09 17:33:18

标签: python

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

我已经设置了此功能,但它不起作用,因为nowcounter变量将被覆盖。所以在其他地方需要这些变量。只是想知道是否有关于这个过程的工作,或者是否有一个python库可以处理这种情况。您的建议将不胜感激!

2 个答案:

答案 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类。但我现在想不出更好的名字,所以我会保持原样。