![](/img/trans.png)
[英]Converting CSV information from str > float > int then assigning it to a value in a dictionary
[英]Set the value of an argument in a class who inherits from int or float or str
當我嘗試設置從str
繼承的類的參數的值時,會引發錯誤。 只有當我嘗試使用myClass(arg = 'test')
訪問參數時才會發生錯誤。 錯誤是:
TypeError: 'arg' is an invalid keyword argument for this function
問題顯示在此示例中:
class A(str):
def __init__(self, arg):
pass
A("test") # Works well
A(arg = "test") # Fails
只有最后一行才會引發錯誤。 前一行效果很好。 從int
或float
繼承的類的問題是相同的。
更新(解決方案):
我找到了這些鏈接的解決方案:
解決方案是:
class A(str):
def __new__(cls, *args, **kwargs):
return str.__new__(cls)
def __init__(self, arg01):
print(arg01)
A(arg01= "test")
我不確切知道為什么會有效,我會對此進行調查。 如果有人有明確的解釋,我很感興趣,我提前感謝他。
更新(我的解釋):
我完全不確定我會說什么,但這就是我的理解。
想象一下沒有任何遺產的班級'myClass'
。 當我這樣做myInstance = myClass()
,會發生以下情況:
執行myClass.__new__
方法。 此方法將創建對象myInstance
。 __new__
是真正的構造函數( __init__
不是構造函數!)。 在偽代碼中, __new__
看起來像這樣:
def __new__ (cls, *args, **kwargs):
myInstance = # Do some stuff to create myInstance, an object of the type passed as argument (cls).
# Add the method __init__ to myInstance.
# Call __init__ and pass to it the list 'args' and the dictionary 'kwargs' (both come from arguments of __new__). Pass to it also the object itself (self) :
obj.__init__(self, args, kwargs) :
# Do some stuff.
當我們使用不可變類型(str,int,float,tuple)時,情況會有所不同。 在之前的偽代碼中,我寫了def __new__(cls, *args, **kwargs)
。 對於不可變類型,方法__new__
的偽代碼__new__
是這個def __new__(cls, anUniqueValue)
。 我並不真正理解為什么immutableTypes.__new__
的行為與其他行為不同,但事實並非如此。 你可以在這個例子中看到它:
class foo():
def __init__(self):
pass
foo.__new__(foo, arg = 1)
# That works because the method __new__ look like this : def __new__(*args, **kargs).
str.__new__(str, arg = 1)
# That fails because we are trying to pass the attribute 'arg' to a method which look like this : def __new__(anUniqueValue).
從那里,我們可以理解為什么之前提出的解決方案有效。 我們所做的是編輯一個不可變類型的方法__new__
,就像一個可變類型一樣工作。
def __new__(cls, *args, **kwargs):
return str.__new__(cls)
這兩def __new__ (cls, anUniqueValue)
轉換為def __new__ (cls, *args, **kwargs)
我希望我的解釋幾乎清楚,沒有太多錯誤。 如果你說法語,你可以學到更多的鏈接: http://sametmax.com/la-difference-entre- 新 -et- 初始化烯蟒蛇/
你所寫的內容基本上是正確的,這里和那里都有一些錯誤。
class A(str):
def __new__(cls, *args, **kwargs):
return str.__new__(cls)
def __init__(self, arg01):
print(arg01)
這不完全正確:如果你沒有將任何參數傳遞給str.__new__
,你的新實例將相當於一個空字符串。
class A(str):
def __new__(cls, arg):
return str.__new__(cls, arg)
def __init__(self, arg):
print(arg)
通常, __init__
__new__
和__init__
應具有相同的簽名。 這不是必需的,但在這種情況下你需要將arg
傳遞給str.__new__
所以你必須攔截arg
。
執行
myClass.__new__
方法。 此方法將創建對象myInstance
。__new__
是真正的構造函數(__init__
不是構造函數!)。 在偽代碼中,__new__
看起來像這樣:
調用__init__
不是__new__
的責任,正如這個簡單的例子所示:
class C:
def __new__(cls):
print('entering __new__')
self = super().__new__(cls)
print('exiting __new__')
return self
def __init__(self):
print('entering __init__')
super().__init__()
print('exiting __init__')
C()
# Output:
# entering __new__
# exiting __new__
# entering __init__
# exiting __init__
正如你所看到的,在我的__new__
我沒有明確地調用__init__
,而object.__new__
也沒有調用__init__
。
每當__new__
返回該類型的實例時,Python解釋器本身就會自動調用__init__
。
當我們使用不可變類型(str,int,float,tuple)時,情況會有所不同。
這不完全正確。 當我們從不使用默認__new__
實現的類型繼承時 ,情況就不同了 。
默認的__new__
實現(即object.__new__
)非常寬松,並忽略每個位置參數和關鍵字參數。 如果用不太寬松的實現替換它,那么就會發生類似你正在觀察的問題。
重要的是要理解的是,問題不是由非默認的__new__
本身引起的,而是由於我們的__init__
與__new__
不兼容 。
foo.__new__(foo, arg = 1) # That works because the method __new__ look like this : def __new__(*args, **kargs). str.__new__(str, arg = 1) # That fails because we are trying to pass the attribute 'arg' to a method which look like this : def __new__(anUniqueValue).
你說對了。 只有一點是錯的: str.__new__
的正確簽名是:
def __new__(cls[, object[, encoding[, errors]]])
除cls
之外的所有參數都是位置和關鍵字參數。 事實上你可以這樣做:
>>> class C(str):
... def __init__(self, object):
... pass
...
>>> C('abc')
'abc'
>>> C(object='abc')
'abc'
你看? 我們使用了__init__
的簽名,它與str.__new__
兼容,現在我們可以避免覆蓋__new__
!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.