كيفية إنشاء كائن datetime باستخدام PyYAML
سؤال
أود أن أكون قادرًا على إنشاء كائن datetime باستخدام datetime.datetime.now()
بييامل.من السهل استدعاء بعض الوظائف:
>>> y = """#YAML
... description: Something
... ts: !!python/object/apply:time.time []"""
>>> yaml.load(y)
{'description': 'Something', 'ts': 1289955567.940973}
>>>
ومع ذلك، يبدو أنني لا أستطيع معرفة كيفية الحصول على datetime.now()
.لقد حاولت العديد من التباديل مع المكالمات لذلك باستخدام مختلف علامات بايثون يامل.
هذه كلها تفشل:
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
المحلول
أعتقد أن هذا المثال يحقق ما تبحث عنه:
dt = yaml.load("""dt: !!python/object/apply:apply
- !!python/object/apply:getattr
- !!python/name:datetime.datetime
- now
- []
""")
ومع ذلك، أعتقد أن هذا بعيد المنال لأنه !!python/object
ليس من المفترض أن يقوم بناء الجملة الذي يدعمه PyYAML باستدعاء أساليب الفصل (datetime.datetime.now
يشبه في الواقع طريقة المصنع "الثابتة" لكائنات التاريخ والوقت).كما قلت، هذا أبسط (على الرغم من أنه ليس ما تبحث عنه):
dt = yaml.load("dt: !!python/object/apply:time.gmtime []")
dt = yaml.load("dt: !!python/object/apply:time.time []")
هناك حل آخر محتمل يتمثل في إنشاء وظيفة مساعد مخصصة تغطي المكالمة datetime.datetime.now
بحيث يتم تسلسلها بسهولة مع !!python/object/apply
.السلبيات هي أن هذا التسلسل لن يكون قابلاً للنقل إلى بيئة لا يتم العثور على هذه الوظيفة المخصصة فيها.
على أي حال، في رأيي أنه ليس من المنطقي إجراء تسلسل لقيمة تُرجع دائمًا التاريخ والوقت الحالي (والذي سيكون في الواقع الوقت الذي تم فيه تحليل YAML).يوفر PyYAML هذا الاختصار لإجراء تسلسل لطابع زمني معين:
dt = yaml.load("""dt: !!timestamp '2010-11-17 13:12:11'""")
نصائح أخرى
تكمن المشكلة في أن الكائن لا يحتوي على طريقة يحتاجها PyYAML لإنشاء تمثيل YAML تلقائيًا.لماذا لا تفعل فقط datetime.datetime.now().isoformat()
وتخزين تلك السلسلة بدلا من ذلك؟
بدلا من ذلك، يمكنك وضع الخصائص المطلوبة لل datetime
كائن في القاموس وتحميل ذلك.
إذا كنت تريد تخزين سلسلة بتنسيق isoformat، فما عليك سوى وضعها في سلسلة ثم تفريغها:
timestamp = datetime.datetime.now().isoformat()
عند قراءتها مرة أخرى، استخدم strptime()
طريقة:
new_dt_object = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f')
بالطبع، ومن المضحك أنني أدركت للتو أنه يمكنك القيام بما يلي:
yaml_timestamp = yaml.dump({'timestamp': datetime.datetime.now()})
إذا قمت بتحميل ذلك مع yaml.load(yaml_timestamp)
, ، ستجد نفسك تمتلك الجديد اللامع datetime.datetime
هدف.