Noch etwas perplex von Python und es ist magische funktionale Programmierung, so tendiere ich dazu, Code zu schreiben, der eher auf das Java-Paradigma der Programmierung im Gegensatz zu Idiomatic Python ist.Wie Python-Sammlungen für benutzerdefinierte Klassen verwenden
Meine Frage ist etwas im Zusammenhang mit: How do I make a custom class a collection in Python
Der einzige Unterschied ist, ich verschachtelte Objekte haben (unter Verwendung von Zusammensetzung). Das Objekt VirtualPage besteht aus einer Liste von Objekten PhysicalPage. Ich habe eine Funktion, die eine Liste von PhyscialPage Objekte nehmen und alle Details in ein einzelnes benanntes Tupel zusammenfügen kann, das ich PageBoundary anruft. Im Wesentlichen ist es eine Serialisierungsfunktion, die ein Tupel ausgeben kann, das aus einem Ganzzahlbereich besteht, der die physikalische Seite und die Zeilennummer auf der Seite darstellt. Daraus kann ich leicht zu sortieren und zu bestellen VirtualPages untereinander (das ist die Idee, zumindest):
PageBoundary = collections.namedtuple('PageBoundary', 'begin end')
Ich habe auch eine Funktion, die einen PageBoundary namedtuple und Deserialisieren oder erweitern Sie den Tupels in eine nehmen kann Liste der PhysicalPages. Es ist vorzuziehen, dass diese beiden Datenspeicherklassen sich nicht ändern, da dadurch der Downstream-Code unterbrochen wird.
Hier ist ein Ausschnitt meiner benutzerdefinierten Python2.7-Klasse. Es besteht aus vielen Dingen ist eine Liste, die eine das Objekt PhysicalPage enthält:
class VirtualPage(object):
def __init__(self, _physical_pages=list()):
self.physcial_pages = _physcial_pages
class PhysicalPage(object):
# class variables: number of digits each attribute gets
_PAGE_PAD, _LINE_PAD = 10, 12
def __init__(self, _page_num=-1):
self.page_num = _page_num
self.begin_line_num = -1
self.end_line_num = -1
def get_cannonical_begin(self):
return int(''.join([str(self.page_num).zfill(PhysicalPage._PAGE_PAD),
str(tmp_line_num).zfill(PhysicalPage._LINE_PAD) ]))
def get_cannonical_end(self):
pass # see get_cannonical_begin() implementation
def get_canonical_page_boundaries(self):
return PageBoundary(self.get_canonical_begin(), self.get_canonical_end())
ich einige Templat-Sammlung nutzen möchten (aus dem Python-Sammlungen Modul) leicht zu sortieren und zu vergleichen, als Liste oder einen Satz von VirtualPage Klassen. Weitere Informationen zum Layout meiner Datenspeicherklassen: VirtualPage und PhysicalPage.
Gegeben entweder eine Folge von VirtualPages oder wie im folgenden Beispiel:
vp_1 = VirtualPage(list_of_physical_pages)
vp_1_copy = VirtualPage(list_of_physical_pages)
vp_2 = VirtualPage(list_of_other_physical_pages)
Ich möchte Fragen leicht beantworten wie folgt aus:
>>> vp_2 in vp_1
False
>>> vp_2 < vp_1
True
>>> vp_1 == vp_1_copy
True
Rechts von der Fledermaus scheint es offensichtlich, dass Die Klasse VirtualPage muss get_cannonical_page_boundaries aufrufen oder die Funktion selbst implementieren. Zumindest sollte es eine Schleife über es PhysicalPage Liste die gewünschten Funktionen zu implementieren (lt() und eq()), so kann ich vergleichen b/w VirtualPages.
1.) Derzeit habe ich Probleme mit der Implementierung einiger Vergleichsfunktionen. Ein großes Hindernis ist, wie man ein Tupel vergleicht. Muss ich meine eigene lt() Funktion, indem Sie eine benutzerdefinierte Klasse erstellen, die irgendeine Art von Sammlung erweitert:
import collections as col
import functools
@total_ordering
class AbstractVirtualPageContainer(col.MutableSet):
def __lt__(self, other):
'''What type would other be?
Make comparison by first normalizing to a comparable type: PageBoundary
'''
pass
2.) Sollte die Vergleichsfunktionsimplementierung stattdessen in der Klasse VirtualPage vorhanden sein?
Ich lehnte mich an irgendeine Art von Set-Datenstruktur, da die Eigenschaften der Daten, die ich modelliere, das Konzept der Eindeutigkeit hat: d.h. physikalische Seitenwerte können sich nicht überlappen und bis zu einem gewissen Grad als verkettete Liste fungieren. Würden auch Setzer- oder Getterfunktionen, die über @ Decorator-Funktionen implementiert werden, hier von Nutzen sein?
Was bedeutet es, 'vp_2 in vp_1' zu sagen? Dass sie mindestens eine physische Seite gemeinsam haben oder alle Seiten in vp_2 sind auch in vp_1? Ähnlich für '<', '==' usw. Sind diese Operationen in Form von physischen Seiten oder PageBoundaries definiert? Ich denke, 'get_cannonical_begin()' kann vereinfacht werden, um 'return self.page_num * 10 ** PhysicalPage._LINE_PAD + tmp_line_num' – RootTwo
Entschuldigen Sie, drücken Sie die Eingabetaste hehe Angenommen, ich beginne mit einem ersten Satz von PhysicalPages in einem Volumen: ** pp_init_set * *. Mein Ziel ist es, ** pp_init_set ** in verschiedene ** VirtualPage ** Objekte zu zerlegen, indem ich ihre Seiten + Zeilenumbrüche in Form von ** PhysicalPages ** definiere. Wenn ich fertig bin, sollte ich eine Liste von einzigartigen ** VirtualPage ** Objekten gesetzt haben. Wenn ich diese Einstellung summiere, sollte ich das Original ** pp_init_set ** bekommen. Dies bedeutet, dass weder Seiten (Löcher) noch überlappende Seiten fehlen. Auch diese Identität gilt: VirtualPage [i] .physical_pages [-1] .end_line_num == VirtuellePage [i + 1] .physical_pages [0] .begin_line_num – Dave
Vielleicht vp_2 in vp_1 ist nicht so nützlich. Ich würde wirklich gerne genug von der Funktion in https://docs.python.org/2/library/collections.html?highlight=collections#collections-abstract-base-classes definieren, um mein eigenes MutableSet von ** VirtualPages zu haben ** was kann ich dann, auf einer hohen Ebene, vp_2 - vp_1, um den Unterschied s/w zwei berühren ** VirtualPages ** zu bekommen. In diesem Fall würde ich erwarten, dass ich eine neue ** VirtualPage ** bekomme, bei der die beiden oben genannten Regeln noch gültig sind. ** PageBoundaries ** ist nur eine einfache Übersetzungsfunktion zur Darstellung einer Liste von ** PhysicalPages **. Danke für die Antwort BTW! – Dave