2016-07-25 37 views
4

Ich brauche eine Klasse, die sich wie eine Zeichenfolge verhält, sondern auch zusätzliche kwargs. Dafür ich Unterklasse str:Create Kind von Str (oder Int oder Float oder Tupel), die Kwarts akzeptiert

class Child(str): 

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


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

Dies jedoch erhöht:

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 

was ziemlich merkwürdig ist, da Sie den Code unten ohne Fehler funktioniert:

class Child(object): 

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


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

Fragen:

  • Warum muss ich ein anderes Verhalten bekommen, wenn zu Unterklasse versuchen str, int, float, tuple usw. im Vergleich zu anderen Klassen wie object, list, dict etc?
  • Wie kann ich eine Klasse erstellen, die sich wie eine Zeichenfolge verhält, aber zusätzliche Kwargs hat?
+0

vielleicht etwas über die Methoden "__str__" oder "__unicode__", die überschrieben werden müssen –

Antwort

7

Sie müssen __new__ in diesem Fall außer Kraft zu setzen, nicht __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' 
>>> 

Siehe here für die Antwort, warum überwiegende __init__ funktioniert nicht, wenn Subklassen unveränderliche Typen wie str, int und 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.