Tôi có mã làm việc trong Python 3.6 và bị lỗi trong Python 3.8. Nó dường như sôi sục để gọi super
trong lớp con của typing.NamedTuple
, như dưới đây:
<ipython-input-2-fea20b0178f3> in <module>
----> 1 class Test(typing.NamedTuple):
2 a: int
3 b: float
4 def __repr__(self):
5 return super(object, self).__repr__()
RuntimeError: __class__ not set defining 'Test' as <class '__main__.Test'>. Was __classcell__ propagated to type.__new__?
In [3]: class Test(typing.NamedTuple):
...: a: int
...: b: float
...: #def __repr__(self):
...: # return super(object, self).__repr__()
...:
>>> # works
Mục đích của super(object, self).__repr__
cuộc gọi này là sử dụng tiêu chuẩn '<__main__.Test object at 0x7fa109953cf8>'
__repr__
thay vì in ra tất cả nội dung của các phần tử bộ (sẽ xảy ra theo mặc định). Có một số câu hỏi về super
kết quả là lỗi tương tự nhưng chúng:
- Tham khảo phiên bản không có tham số
super()
- Đã có lỗi trong Python 3.6 (nó hoạt động với tôi trước khi nâng cấp 3.6 -> 3.8)
- Tôi không hiểu làm thế nào để sửa lỗi này, vì nó không phải là siêu dữ liệu tùy chỉnh mà tôi có quyền kiểm soát mà là do stdlib cung cấp
typing.NamedTuple
.
Câu hỏi của tôi là làm thế nào tôi có thể sửa lỗi này trong khi duy trì khả năng tương thích ngược với Python 3.6 (nếu không tôi chỉ sử dụng @dataclasses.dataclass
thay vì kế thừa từ typing.NamedTuple
)?
Một câu hỏi phụ là làm thế nào điều này có thể thất bại tại thời điểm xác định cho rằng super
cuộc gọi vi phạm nằm trong một phương thức thậm chí chưa được thực hiện. Ví dụ:
In [3]: class Test(typing.NamedTuple):
...: a: int
...: b: float
...: def __repr__(self):
...: return foo
hoạt động (cho đến khi chúng tôi thực sự gọi __repr__
) mặc dù foo
là một tham chiếu không xác định. Là super
ma thuật trong vấn đề đó?
__repr__ = object.__repr__
trong định nghĩa lớp của bạn hoạt động với tôi trên Python3.6 & Python3.8
typing.NamedTuple
; typing.NamedTupleMeta
, đó là làm một số shenanigans. super()
yêu cầu __class__
phải có sẵn tại thời gian biên dịch , rõ ràng không phải là trường hợp ở đây. Xem thêm: Cung cấp __classcell__
ví dụ cho siêu dữ liệu Python 3.6
super
chính đối tượng, không phải là đại diện cho thể hiện của bạnTest
.