2010-11-17 13 views
5

Chciałbym móc utworzyć obiekt datetime z datetime.datetime.now() PyYAML. Łatwo wywołać pewne funkcje:Jak utworzyć obiekt datetime z PyYAML

>>> y = """#YAML 
... description: Something 
... ts: !!python/object/apply:time.time []""" 
>>> yaml.load(y) 
{'description': 'Something', 'ts': 1289955567.940973} 
>>> 

Jednak nie wydaje się dowiedzieć się, jak uzyskać datetime.now(). Próbowałem już tylu permutacji z połączeniami do tego, używając różnych python yaml tags.

Te wszystkie zawieść:

tests = [ 
     'dt: !!python/object:datetime.datetime.now []', 
     'dt: !!python/object/new:datetime.datetime.now []', 
     'dt: !!python/object/apply:datetime.datetime.now []', 
] 

for y in tests: 
    try: 
     print yaml.load(y) 
    except Exception, err: 
     print '==>', err 

Odpowiedz

5

myślę, że ten przykład osiąga to, czego szukasz:

dt = yaml.load("""dt: !!python/object/apply:apply 
    - !!python/object/apply:getattr 
     - !!python/name:datetime.datetime 
     - now 
    - [] 
""") 

Myślę jednak, że jest to zbyt daleko idące, ponieważ składnia !!python/object poparte PyYAML nie powinien wywoływać metody klasy (datetime.datetime.now jest w rzeczywistości jak "statyczna" metoda fabryczna dla obiektów datetime). Jak pan powiedział, jest to prostsze (choć nie tego szukasz):

dt = yaml.load("dt: !!python/object/apply:time.gmtime []") 
dt = yaml.load("dt: !!python/object/apply:time.time []") 

Innym możliwym obejście byłoby utworzyć niestandardową funkcję pomocnika, który otacza wezwanie do datetime.datetime.now tak, że jest łatwo odcinkach z !!python/object/apply. Wady polegają na tym, że ta serializacja nie byłaby przenośna w środowisku, w którym nie znaleziono tej niestandardowej funkcji.

W każdym razie, moim zdaniem, nie ma większego sensu szeregowanie wartości, która zawsze zwraca bieżącą datę i godzinę (co faktycznie byłby czas, w którym YAML został przeanalizowany). PyYAML udostępnia ten skrót do serializowania określonego znacznika czasu:

dt = yaml.load("""dt: !!timestamp '2010-11-17 13:12:11'""") 
+0

Bardzo ładne. Zgadzam się, że jest to nieco zawiły przypadek użycia, ale twoje rozwiązanie wygląda na najprostszy sposób. Dla kontekstu badam użycie YAML do generowania danych testowych, które zostaną załadowane przez Django. Posiadanie danych generowanych podczas ładowania pliku byłoby ogromną korzyścią dla wielu testów. Dziękuję za odpowiedź! – brianz

+1

fwiw, z 'zastosować' usunięty w python 3 przykład nie działa. To powiedziawszy, nie zamierzam tego robić, tylko natknąłem się na tę odpowiedź, wykonując kilka badań :) (wow 'pyyaml' jest szalony!) –

0

Problemem jest to, że obiekt nie ma metody, która PyYAML potrzebne do automatycznego generowania reprezentacji YAML. Dlaczego nie po prostu zrobić datetime.datetime.now().isoformat() i zapisać ten ciąg zamiast?

Alternatywnie, możesz umieścić żądane właściwości obiektu datetime w słowniku i załadować go.

Jeśli chcesz przechowywać ciąg isoformat, wystarczy umieścić go na sznurku i zrzucić go:

timestamp = datetime.datetime.now().isoformat()

Kiedy czytasz go z powrotem, należy użyć metody strptime():

new_dt_object = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f')

Oczywiście, uświadomiłem sobie, że możesz po prostu zrobić:

yaml_timestamp = yaml.dump({'timestamp': datetime.datetime.now()})

Jeśli załadować że z yaml.load(yaml_timestamp), znajdziesz się w posiadaniu błyszczące nowej datetime.datetime obiektu.

+0

Problem polega na tym, że chciałbym, aby to zostało wygenerowane dynamicznie po wczytaniu pliku yaml. Czy twoje drugie rozwiązanie to wykona? – brianz

+0

Właściwie błędnie przeczytałem twoje pytanie; Myślałem, że chcesz przechowywać obiekt datetime. Mimo to możesz użyć metody '.isoformat()' do wygenerowania ciągu znaków, a następnie użyć 'strptime()' (http://docs.python.org/library/datetime.html#datetime.datetime.strptime) do przekonwertuj ciąg znaków na obiekt datetime. – syrion

+0

A jak dokładnie zrobiłbyś to dynamicznie w pliku yaml używając pyyaml? – brianz

Powiązane problemy