2016-07-25 5 views
4

Мне нужен класс, который ведет себя как строка, но также принимает дополнительные kwargs. Therefor I подкласс str:Создайте дочерний элемент str (или int или float или tuple), который принимает kwargs

class Child(str): 

    def __init__(self, x, **kwargs): 
     # some code ... 
     pass 


inst = Child('a', y=2) 
print(inst) 

Это, однако, вызывает:

Traceback (most recent call last): 
    File "/home/user1/Project/exp1.py", line 8, in <module> 
    inst = Child('a', y=2) 
TypeError: 'y' is an invalid keyword argument for this function 

Что довольно странно, так как код ниже работает без каких-либо ошибок:

class Child(object): 

    def __init__(self, x, **kwargs): 
     # some code ... 
     pass 


inst = Child('a', y=2) 

Вопросы:

  • Почему я получаю различное поведение при попытке создать подкласс str, int, float, tuple и т.д. по сравнению с другими классами, как object, list, dict и т.д.?
  • Как создать класс, который ведет себя как строка, но имеет дополнительных kwargs?
+0

может быть что-то о методах '__str__' или' __unicode__', которые необходимо переопределить –

ответ

7

Вы должны переопределить __new__ в этом случае не __init__:

>>> class Child(str): 
... def __new__(cls, s, **kwargs): 
...  inst = str.__new__(cls, s) 
...  inst.__dict__.update(kwargs) 
...  return inst 
... 
>>> c = Child("foo") 
>>> c.upper() 
'FOO' 
>>> c = Child("foo", y="banana") 
>>> c.upper() 
'FOO' 
>>> c.y 
'banana' 
>>> 

См here ответ, почему наиважнейшая __init__ не работает, когда подклассы неизменных типов, как str, int и float:

__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

 Смежные вопросы

  • Нет связанных вопросов^_^