Ошибка при попытке установить значение аргумента класса, который наследует от str
. Ошибка возникает только тогда, когда я пытаюсь получить доступ к аргументу с помощью myClass(arg = 'test')
. Ошибка:Задайте значение аргумента в классе, который наследует от int или float или str
TypeError: 'arg' is an invalid keyword argument for this function
вопрос показан в этом Exemple:
class A(str):
def __init__(self, arg):
pass
A("test") # Works well
A(arg = "test") # Fails
только последняя строка вызывает ошибку. Предыдущая строка работает хорошо. Проблема такая же с классами, которые наследуются от int
или float
.
ОБНОВЛЕНИЕ (раствор):
Я нашел решение с этих ссылок:
- Adding optional parameters to the constructors of multiply-inheriting subclasses of built-in types?
- inheritance from str or int
Раствор является:
class A(str):
def __new__(cls, *args, **kwargs):
return str.__new__(cls)
def __init__(self, arg01):
print(arg01)
A(arg01= "test")
Я не знаю, почему это работает, и я буду исследовать его. Если у кого-то есть ясное объяснение, я заинтересован, и я благодарю его заранее.
UPDATE (мое объяснение):
Я не уверен, что на все, что я скажу, но это то, что я понял.
Представьте себе класс '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.
ситуация немного отличается, когда мы используем неизменные типы (улица, целый, дробный, кортеж). В предыдущем псевдокоде я написал def __new__(cls, *args, **kwargs)
. С неизменяемыми типами псевдокод для метода __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)
Эти 2 строки преобразуют def __new__ (cls, anUniqueValue)
в def __new__ (cls, *args, **kwargs)
Я надеюсь, что мое объяснение почти ясно и без так много ошибок.Если вы говорите по-французски, вы можете узнать больше по этой ссылке: http://sametmax.com/la-difference-entre-new-et-init-en-python/
Возможно, связано с http://stackoverflow.com/questions/3748635/adding-optional-parameters-to-the-constructors-of-multiply-inheriting-subclasses, хотя я не уверен, что Алекс Мартелли точно означает " одинаково произвольный суперкласс ". – timgeb
@Morgan, объяснение в связанном вопросе, может также быть * ее *, который может дать вам четкое объяснение;) –
@Morgan не стесняйтесь отвечать на свой вопрос, когда узнаете, что именно происходит на. Я сам не полностью понял объяснения в связанных вопросах. – timgeb