Tôi giả sử bạn đang sử dụng CPython chứ không phải triển khai Python khác. Và tôi có thể tái sản xuất vấn đề với CPython 3.6.1 (Tôi không có PyPy, Jython, IronPython, ... vì vậy tôi không thể kiểm tra những điều này).
Người phạm tội trong trường hợp này là thay thế PyObject_Call
bằng _PyObject_CallNoArg
trong tương đương C của callable_iterator.__next__
(đối tượng của bạn là phương thức callable_iterator
).
PyObject_Call
trả về datetime.datetime
trường hợp mới trong khi _PyObject_CallNoArg
trả về NULL
(tương đương với ngoại lệ trong Python).
Đào một chút thông qua mã nguồn CPython:
Các _PyObject_CallNoArg
chỉ là một vĩ mô cho _PyObject_FastCall
do đó là một vĩ mô cho _PyObject_FastCallDict
.
This _PyObject_FastCallDict
function kiểm tra loại chức năng (C
-chức năng hoặc hàm Python hoặc cái gì khác) và ủy quyền cho _PyCFunction_FastCallDict
trong trường hợp này là datetime.now
là hàm C.
Kể từ datetime.datetime.now
có METH_FASTCALL
cờ nó kết thúc trong thứ tư case
nhưng có _PyStack_UnpackDict
lợi nhuận NULL
và hàm được thậm chí không bao giờ gọi.
Tôi sẽ dừng ở đó và để cho các nhà phát triển Python tìm hiểu xem có gì sai trong đó. @Martijn Pieters đã gửi một báo cáo lỗi và họ sẽ sửa chữa nó (tôi chỉ hy vọng họ sửa chữa nó sớm).
Vì vậy, đó là lỗi mà họ đã giới thiệu trong 3.6 và cho đến khi được khắc phục, bạn cần đảm bảo phương pháp không phải là CFunction
với cờ METH_FASTCALL
. Như cách giải quyết bạn có thể quấn nó.Ngoài các khả năng @Martijn Pieters đã đề cập cũng có một cách đơn giản:
def now():
return datetime.datetime.now()
j = iter(now, None)
next(j) # datetime.datetime(2017, 5, 31, 14, 23, 1, 95999)
Thú vị, tôi hy vọng điều này sẽ hoạt động. Nó hoạt động trong 3,4 và 3,5 quá. –
Nó hoạt động khi bạn thay thế 'datetime.datetime.now' bằng' lambda: datetime.datetime.now() 'hoặc' partial (datetime.datetime.now) '. –
Tôi đoán bạn nên báo cáo điều này tại [bug tracker] của họ (https://bugs.python.org/). – MSeifert