Ersetzen __str__ Methode auf Liste Objekt in Python
-
06-09-2019 - |
Frage
Dies scheint, wie es sollte einfach sein:
Ich möchte ein list
wie jedes andere list
, außer es eine andere .__str__
Methode hat.
- Der Versuch,
object.__str__ = foo
Ergebnisse in einem Nur-Lese-Fehler auf - Der Versuch,
list
zu Unterklasse bedeutet, dass Sie einen Weg benötigen eine bestehendelist
zu einer Instanz der Unterklasse zu konvertieren. Dies erfordert entweder Kopieren alle Attribute manuell (ein großer Schmerz) oder irgendwie kopieren sie alle automatisch, was ich weiß nicht, wie zu tun. - Der Versuch, einen Wrapper zu schreiben um das
list
Objekt bedeutet, dass ich einen Weg, um herauszufinden, alle Nachrichten zu dem umwickelten Gegenstand außer.__str__
zu senden, die ich mit meiner eigenen Methode behandeln. Sie wissen nicht, wie dies zu tun.
Jede Alternativen oder Lösungen # 2 oder # 3 sehr geschätzt. Dank!
Lösung
Diese Lösung funktioniert ohne Wrapper. Und funktioniert, wenn Sie zwei Listen von Add beizutreten. Jede Operation, die die Liste selbst ändern wird erwartet funktionieren. Nur Funktionen, die eine Kopie der Liste wie zurückgeben: sortiert, die native Python Liste reveresed zurückkehren, die in Ordnung ist. Art und rückwärts auf der anderen Seite arbeitet auf der Liste selbst und die Art halten.
class myList(list):
def __new__(cls, data=None):
obj = super(myList, cls).__new__(cls, data)
return obj
def __str__(self):
return 'myList(%s)' % list(self)
def __add__(self, other):
return myList(list(self) + list(other))
>>> l = myList(range(5))
>>> print l
myList([0, 1, 2, 3, 4])
>>> print l + [1, 2]
myList([0, 1, 2, 3, 4, 1, 2])
>>> l.sort()
>>> print l
myList([0, 1, 2, 3, 4])
Andere Tipps
Wenn Sie __str__
für andere Behälter außer Kraft setzen möchte (zum Beispiel tuple
), können Sie die Vorteile von Mehrfachvererbung nehmen können:
class PrettyStr(object):
def __str__(self):
ret = ''
if isinstance(self, (list, tuple)):
ret = ''.join(str(elem) for elem in self)
else:
pass # handle other types here
return ret
class MyList(PrettyStr, list):
pass
class MyTuple(PrettyStr, tuple):
pass
if __name__ == "__main__":
print MyList([1, 2, 3, 4])
print MyTuple((1, 2, 3, 4))
Sie können die Liste Klasse erweitern und außer Kraft setzen es:
class myList(list):
def __str__(self):
# do something
return "something"
Edit:. Ein falsche Teil der Antwort entfernt, die auf der Liste Objekt dynamisch ersetzt __str__
vorgeschlagen, die nicht bei der Implementierung von Python-Listen erlaubt ist
Ich bin ein Java-Programmierer, aber ich denke, das ist, was Sie (getestet mit Python 2.6) wollen:
>>> class myList(list):
... def __str__(self):
... return "aaa"
...
>>> def myListWrapper(list):
... return myList(list)
...
>>> a = [1, 2, 3]
>>> type(a)
<type 'list'>
>>> b = myListWrapper(a)
>>> type(b)
<class '__main__.myList'>
>>> print(a)
[1, 2, 3]
>>> print(b)
aaa
class MyList(list):
def __str__(self):
return "foo"
str(MyList([1, 2, 3]))
'foo'
str(MyList(list([1, 2, 3])))
'foo'
Meine früheren Kommentare als Antwort. Wie Sie sehen können MyList jede Sequenz in seinem Konstruktor akzeptiert.
was die Frage aufwirft: Warum wollen Sie das __str__ Methode außer Kraft setzen möchten
Wäre es nicht besser, eine Klasse zu erstellen, Ihr Objekt zu kapseln?
class MyContainer(object):
def __init__(self, list):
self.containedList = list
def __str__(self):
print('All hail Python')
Auf diese Weise müssen Sie über das Konvertieren von Ihrem Objekt keine Sorge, oder die Attribute zu kopieren oder zu löschen. (Übrigens, wie teuer ist MyList (Longlist)? Ist es eine intelligente Kopie oder ein dumme „lassen Sie sich eine Liste Objekt aus einer abzählbaren neu?“)
Wenn irgendwann, es kompliziert aussieht zu tun, was Sie versuchen, es zu tun, könnte bedeuten, dass Sie tun es falsch: p
Wie wäre es die Liste Einwickeln?
>>> class StrList(object):
def __init__(self, data=None):
self._data = data or []
def __str__(self):
return "StrList!"
def __getattr__(self, attr):
if attr == "_data":
return self.__dict__[attr]
return getattr(self._data, attr)
def __setattr__(self, key, val):
if key == "_data":
self.__dict__[key] = val
else:
setattr(self._data, key, val)
def __getitem__(self, index):
return self._data[index]
def __setitem__(self, index, value):
self._data[index] = value
>>> l = StrList(range(3))
>>> print l
StrList!
>>> l[0]
0
>>> for x in l:
print x
0
1
2
>>> l[0] = "spam"
>>> l.append("egg")
>>> print list(l)
['spam', 1, 2, 'egg']
>>>
Ex = ["a", 2, 4] #our_list
Ex(-1) = "xuxu_beleza" #the_name_of_your_list(index) = new_item
Print(Ex)
["a", 2, "xuxu_beleza"] #our_new_list
**list[index] = new_item**