我正在嘗試創建一個Sprite
繼承泛型類T
的類,并限制為類的子類Object
。類Text
是類的子類Object
。這是 class Text
,由外部庫提供:
# text.py
class Text(Object):
# ignored properties...
def __init__(self, text="placeholder text", **kwargs):
super().__init__(object_type=Text.object_type, text=text, **kwargs)
這是我自己寫的課Sprite
:
# sprite.py
from typing import TypeVar, Generic
T = TypeVar('T', bound=Object)
class Sprite(Generic[T]):
def __init__(self, **kwargs):
super(Sprite, self).__init__(self, clickable=True, evt_handler=self.click_wrapper, **kwargs)
這樣的Sprite
實體由以下方式初始化:
sprite = Sprite[Text](
text="This is a sprite!",
object_id="spriteTest",
# other similar arguments...
)
這是拋出的錯誤:
Exception thrown in main()! Terminating main...
Traceback (most recent call last):
File "sprite.py", line 79, in main
sprite = Sprite[Text](
File "C:\ProgramData\Anaconda3\lib\typing.py", line 687, in __call__
result = self.__origin__(*args, **kwargs)
File "sprite.py", line 47, in __init__
super(Sprite, self).__init__(self, clickable=True, evt_handler=self.click_wrapper, **kwargs)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
為什么這不起作用?
uj5u.com熱心網友回復:
我相信您在這里誤解了通用型別變數。讓我首先嘗試將您的錯誤減少到最小的變體:
class Sprite:
def __init__(self, **kwargs):
super().__init__(**kwargs)
Sprite(text="My text")
這個非常簡單的程式會拋出與您完全相同的例外:
Traceback (most recent call last):
File ".../72690805.py", line 57, in <module>
Sprite(text="My text")
File ".../72690805.py", line 55, in __init__
super().__init__(**kwargs)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
這里的關鍵是,object
除了一個引數之外,您不能為誰指定任何內容。換句話說,在我們的兩種情況下,超類Sprite
都是object
(即默認的 Python 物件,而不是您的Object
類)。您的Sprite
類根本沒有非默認超類。
您似乎明白,只要您使用,您的super(...).__init__(...)
呼叫就會初始化,但事實并非如此。讓我舉一個使用中的通用型別變數的常見示例:Text
Sprite[Text](...)
from typing import List, TypeVar, Generic
T = TypeVar('T')
class Queue(Generic[T]):
def __init__(self) -> None:
super().__init__()
self.queue: List[T] = []
def put(self, task: T) -> None:
self.queue.append(task)
def get(self) -> T:
return self.queue.pop(-1)
queue = Queue()
queue.put(12)
queue.put(24)
queue.put(36)
# queue.put('a') # <- A type checker should disallow this
print(queue.get())
print(queue.get())
print(queue.get())
在這里,我們有一個簡單的 Queue 類,帶有put
和get
方法。這些函式通過 T 補充了型別提示,現在型別檢查器知道例如Queue[int]().get
回傳一個int
. 但是,這super().__init__()
仍然只是 Python 的標準初始化object
。我們不會突然初始化一個int
,這相當于您似乎正在嘗試的。
總結;每當您發現自己使用typing
模塊中的功能來嘗試使某些東西正常作業時,那么您就犯了一個錯誤。據我所知,來自的所有功能typing
都只是“裝飾性的”,并且被 Python 忽略了。它的存在是為了允許開發人員使用型別檢查器來確保他們不會出錯,例如在初始化queue.put('a')
時呼叫. 重申一下,這個字符仍然會在 Python 中執行,并且會將字符放入佇列中,即使型別檢查器會告訴您它是錯誤的。queue
Queue[int]()
put
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/494511.html
標籤:Python python-3.x 仿制药 极好的