Python (3.x) Skripte Lassen Sie betrachten:Python Kreis Importe wieder einmal (auch bekannt als was mit diesem Entwurf nicht stimmt)
main.py:
from test.team import team
from test.user import user
if __name__ == '__main__':
u = user()
t = team()
u.setTeam(t)
t.setLeader(u)
Test/user.py:
from test.team import team
class user:
def setTeam(self, t):
if issubclass(t, team.__class__):
self.team = t
Test/team.py:
from test.user import user
class team:
def setLeader(self, u):
if issubclass(u, user.__class__):
self.leader = u
Nein Natürlich habe ich kreisförmigen Import und großartigen ImportError.
Also, nicht Pythonista sein, habe ich drei Fragen. Zunächst einmal:
i. Wie kann ich das Ding zum Laufen bringen?
Und zu wissen, dass jemand wird unweigerlich sagen "Circular Importe zeigen immer ein Design-Problem", die zweite Frage kommt:
ii. Warum ist dieses Design schlecht?
Und schließlich drittens ein:
iii. Was wäre eine bessere Alternative?
Um genau zu sein, Typprüfung wie oben ist nur ein Beispiel, es gibt auch eine Indexschicht basierend auf Klasse, die erlaubt, dh. Hier finden Sie alle Benutzer Mitglieder eines Teams (Benutzerklasse hat viele Unterklassen, so Index verdoppelt wird, für die Nutzer im Allgemeinen und für jede spezifische Unterklasse) sein oder alle Teams bestimmten Benutzer als Mitglied mit
Edit:
Ich hoffe, dass detailliertere Beispiele klären, was ich versuche zu erreichen. Dateien für bessere Lesbarkeit weggelassen (aber eine 300kb Quelldatei mit schreckt mich irgendwie, so übernehmen Sie bitte, dass jede Klasse in verschiedenen Datei)
# ENTITY
class Entity:
_id = None
_defs = {}
_data = None
def __init__(self, **kwargs):
self._id = uuid.uuid4() # for example. or randint(). or x+1.
self._data = {}.update(kwargs)
def __settattr__(self, name, value):
if name in self._defs:
if issubclass(value.__class__, self._defs[name]):
self._data[name] = value
# more stuff goes here, specially indexing dependencies, so we can
# do Index(some_class, name_of_property, some.object) to find all
# objects of some_class or its children where
# given property == some.object
else:
raise Exception('Some misleading message')
else:
self.__dict__[name] = value
def __gettattr__(self, name):
return self._data[name]
# USERS
class User(Entity):
_defs = {'team':Team}
class DPLUser(User):
_defs = {'team':DPLTeam}
class PythonUser(DPLUser)
pass
class PerlUser(DPLUser)
pass
class FunctionalUser(User):
_defs = {'team':FunctionalTeam}
class HaskellUser(FunctionalUser)
pass
class ErlangUser(FunctionalUser)
pass
# TEAMS
class Team(Entity):
_defs = {'leader':User}
class DPLTeam(Team):
_defs = {'leader':DPLUser}
class FunctionalTeam(Team):
_defs = {'leader':FunctionalUser}
und jetzt einige Nutzung:
t1 = FunctionalTeam()
t2 = DLPTeam()
t3 = Team()
u1 = HaskellUser()
u2 = PythonUser()
t1.leader = u1 # ok
t2.leader = u2 # ok
t1.leader = u2 # not ok, exception
t3.leader = u2 # ok
# now , index
print(Index(FunctionalTeam, 'leader', u2)) # -> [t2]
print(Index(Team, 'leader', u2)) # -> [t2,t3]
Also, es funktioniert super (Implementierungsdetails sind weggelassen, aber es gibt nichts Kompliziertes) abgesehen von diesem unheiligen zirkulären Import-Ding.
Es wird als gute Übung angesehen, Ihre Klassen zu kapitalisieren - Team/Benutzer. – snapshoe
Außerdem: Auschecken Python [Eigenschaften] (http://docs.python.org/library/functions.html#property) für die bevorzugte Alternative zu Setter und Getters zu deklarieren. – intuited
@intuited: ich liebe Dekorateure, aber anscheinend funktioniert es nicht großartig mit __setattr__/__getattr__ (Beispiel oben ist eher vereinfacht) –