Почему функция `datetime.strptime` в python не ведет себя так же, когда вызывается с помощью` functools.partial`? - PullRequest
3 голосов
/ 25 июня 2019

Вот пример ошибки, с которой я сталкиваюсь:

In [1]: from functools import partial                                                                                             

In [2]: from datetime import datetime                                                                                             

In [3]: datetime.strptime("2/3/2016", "%m/%d/%Y")                                                                                 
Out[3]: datetime.datetime(2016, 2, 3, 0, 0)

In [4]: partial(datetime.strptime, "%m/%d/%Y")("2/3/2016")                                                                        
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-d803aff4879c> in <module>
----> 1 partial(datetime.strptime, "%m/%d/%Y")("2/3/2016")

~/miniconda3/envs/ROS/lib/python3.6/_strptime.py in _strptime_datetime(cls, data_string, format)
    563     """Return a class cls instance based on the input string and the
    564     format string."""
--> 565     tt, fraction = _strptime(data_string, format)
    566     tzname, gmtoff = tt[-2:]
    567     args = tt[:6] + (fraction,)

~/miniconda3/envs/ROS/lib/python3.6/_strptime.py in _strptime(data_string, format)
    360     if not found:
    361         raise ValueError("time data %r does not match format %r" %
--> 362                          (data_string, format))
    363     if len(data_string) != found.end():
    364         raise ValueError("unconverted data remains: %s" %

ValueError: time data '%m/%d/%Y' does not match format '2/3/2016'

Как мне заставить datetime.strptime вести себя правильно, используя partial?Это проблема с тем, как я использую partial или как я использую datetime.strptime?

Ответы [ 2 ]

4 голосов
/ 25 июня 2019

Вы передаете формат (который должен быть вторым параметром) как сначала strptime через partial, а затем передаете строку даты (которая должна быть первым параметром), приводя кошибка.

Вы не можете использовать datetime.strptime с partial таким образом, так как он не принимает никакого ключевого аргумента.Вместо этого вы можете использовать обычную функцию:

In [246]: def get_dt(string): 
     ...:     return datetime.strptime(string, "%m/%d/%Y") 
     ...:                                                                                                                                                                                                   

In [247]: get_dt("2/3/2016")                                                                                                                                                                                
Out[247]: datetime.datetime(2016, 2, 3, 0, 0)
0 голосов
/ 25 июня 2019

Обязательно примите ответ Бимейла. У меня есть пара вещей, которые могут быть полезны.

Это правда, проблема, которую вы видели, была с упорядочением "аргументов" до partial:

>>> from functools import partial  
>>> from datetime import datetime  
>>> datetime.strptime("2/3/2016", "%m/%d/%Y") 
datetime.datetime(2016, 2, 3, 0, 0)
>>> partial(datetime.strptime, "%m/%d/%Y")("2/3/2016")
Traceback (most recent call last):
    ValueError: time data '%m/%d/%Y' does not match format '2/3/2016'

И действительно, если вы измените аргументы, partial работает:

>>> partial(datetime.strptime, "2/3/2016")("%m/%d/%Y")
datetime.datetime(2016, 2, 3, 0, 0)

Но это, конечно, не то, что вы хотите.

Итак, вы можете подумать, что можете воспользоваться преимуществами kwargs здесь ... на самом деле, если вы посмотрите на документы, там написано:

classmethod datetime.strptime (date_string, формат)

Возвращает дату и время, соответствующие строке date_string, проанализированные в соответствии с форматом.

Итак, давайте попробуем это:

>>> partial(datetime.strptime, format="%m/%d/%Y")("2/3/2016")
Traceback (most recent call last):
    TypeError: strptime() takes no keyword arguments

Не принимает аргументов с ключевыми словами! КАКИЕ?! Ну да, большинство функций, которые "исходят из C", на самом деле этого не делают! По умолчанию функции, которые вы пишете сами в Python, всегда будут иметь kwargs, если только вы не используете замечательную новую функцию, начиная с Python 3.8, которая позволяет вам запрещать их .

Интересно, если вы сделаете свой собственный strptime:

>>> def my_strptime(date_string, format):
...     return datetime.strptime(date_string, format)
... 

Тогда вы можете делать, что хотите!

>>> partial(my_strptime, format="%m/%d/%Y")("2/3/2016")
datetime.datetime(2016, 2, 3, 0, 0)

при условии, что вы используете kwarg format.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...