2010-11-17 35 views
5

Tôi muốn có thể tạo đối tượng datetime với datetime.datetime.now() PyYAML. Thật dễ dàng để gọi một số chức năng:Cách tạo đối tượng datetime với PyYAML

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

Tuy nhiên, tôi không thể tìm ra cách để có được datetime.now(). Tôi đã thử nhiều hoán vị với các cuộc gọi đến đó bằng cách sử dụng python yaml tags khác nhau.

Những tất cả thất bại:

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 

Trả lời

5

Tôi nghĩ rằng ví dụ này đạt được những gì bạn đang tìm kiếm:

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

Tuy nhiên, tôi nghĩ rằng đó là quá xa vời vì cú pháp !!python/object hỗ trợ bởi PyYAML là không được phép gọi các phương thức lớp (datetime.datetime.now là thực sự giống như phương thức nhà máy "tĩnh" cho các đối tượng ngày giờ). Như bạn nói, đây là đơn giản hơn (mặc dù không phải những gì bạn đang tìm kiếm):

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

Một công việc xung quanh có thể sẽ tạo ra một chức năng tùy chỉnh helper mà kết thúc tốt đẹp các cuộc gọi đến datetime.datetime.now để nó có thể dễ dàng serialized với !!python/object/apply. Các khuyết điểm là serialization này sẽ không được di chuyển đến một môi trường mà không tìm thấy chức năng tùy chỉnh này. Dù sao, theo ý kiến ​​của tôi, nó không có ý nghĩa quá nhiều để sắp xếp một giá trị luôn luôn trả về datetime hiện tại (đây thực sự là thời gian khi YAML được phân tích cú pháp). PyYAML cung cấp lối tắt này để tuần tự hóa một dấu thời gian nhất định:

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

Rất đẹp. Tôi đồng ý rằng đây là trường hợp sử dụng hơi phức tạp, nhưng giải pháp của bạn trông giống như cách dễ nhất để thực hiện. Đối với ngữ cảnh, tôi đang điều tra bằng cách sử dụng YAML để tạo ra dữ liệu thử nghiệm sẽ được tải thông qua Django. Có dữ liệu được tạo khi tệp được tải sẽ là một lợi ích rất lớn cho nhiều thử nghiệm. Cảm ơn câu trả lời! – brianz

+1

fwiw, với 'apply' được loại bỏ trong python 3 ví dụ không còn hoạt động nữa. Điều đó nói rằng, tôi không thực sự tìm cách để làm điều này chỉ vấp trên câu trả lời này trong khi làm một số nghiên cứu :) (wow 'pyyaml' là điên!) –

0

Vấn đề là đối tượng không có một phương pháp mà PyYAML cần phải tự động tạo ra các đại diện YAML. Tại sao không chỉ làm datetime.datetime.now().isoformat() và lưu chuỗi đó thay thế?

Cách khác, bạn có thể đặt các thuộc tính mong muốn của đối tượng datetime trong từ điển và tải nó.

Nếu bạn muốn lưu trữ các chuỗi isoformat, chỉ cần đặt nó vào một chuỗi và đổ nó:

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

Khi bạn đọc nó trở lại, sử dụng strptime() phương pháp:

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

Tất nhiên, vui nhộn, tôi vừa mới nhận ra rằng bạn chỉ có thể làm:

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

Nếu bạn tải điều đó với yaml.load(yaml_timestamp), bạn sẽ thấy mình sở hữu một đối tượng datetime.datetime sáng bóng mới.

+0

Vấn đề là tôi muốn động này được tạo tự động khi tệp yaml được tải. Giải pháp thứ hai của bạn sẽ đạt được điều đó? – brianz

+0

Thực ra, tôi đã đọc sai câu hỏi của bạn; Tôi đã nghĩ bạn muốn lưu trữ đối tượng datetime. Điều đó nói rằng, bạn có thể sử dụng phương thức '.isoformat()' để tạo một chuỗi, sau đó sử dụng 'strptime()' (http://docs.python.org/library/datetime.html#datetime.datetime.strptime) để chuyển đổi chuỗi thành đối tượng datetime. – syrion

+0

Và làm thế nào chính xác bạn sẽ làm điều đó tự động trong một tập tin yaml sử dụng pyyaml? – brianz

Các vấn đề liên quan