Systemabhängig verschiedene Klassen instanzieren

Objektorientierte Skriptsprache: (python.org)
Antworten
Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Systemabhängig verschiedene Klassen instanzieren

Beitrag von Dirty Oerti » Mo Jul 04, 2011 9:53 pm

Tag zusammen :)

Das ist keine Frage, mehr eine Info. Eigentlich gehört sowas ja ins Wiki, da haben wir aber im Bezug auf Python noch viel zu wenig, als dass ich das sinnvoll einordnen kann. Außerdem hätte ich gerne Resonanz zu der grundsätzlich angewandten Technik.

Problemstellung ist:
Ich habe eine gewisse Funktionalität, die ich in Form einer Klasse anbieten will.
Die Schnittstelle ist fest vorgegeben.
Die Funktionalität ist jedoch auf verschiedenen Betriebssystemen unterschiedlich zu implementieren.
Davon soll der Nutzer der Funktionalität aber rein gar nichts mitbekommen.

Mein Ansatz dazu war nun der folgende:


Ein Modul "Func", das die Schnittstelle der Funktionalität bereitstellt.
Ein Modul "XXXXFunc", wobei XXXX für die jeweilige Plattform steht, welches die Funktionalität implementiert.

Code: Alles auswählen

class Func(object):
  def __new__(cls, *args, **kwargs):
    return object.__new__(platform_cls)
Nun musst natürlich zur Laufzeit die zu verwendende Klasse "platform_cls" gefunden werden.
Basis der Überlegungen bildete folgende Funktion:

Code: Alles auswählen

def get_class( kls ):
  parts = kls.split('.')
  module = ".".join(parts[:-1])
  if module:
    m = __import__( module )
    for comp in parts[1:]:
      m = getattr(m, comp)
  return m
Ergebnis der Bastelei:

Ein Package "functionality", das die Schnittstelle im Modul "Func" enthält und, je nach System, die Implementierung "XXXXFunc"

functionality:
--- __init__.py
--- Func.py
--- LinuxFunc.py

__init__.py ist leer, könnte z.B. so eingestellt werden, dass nur Func imported wird, sollte jemand das ganze Package importieren.

Func.py

Code: Alles auswählen

import platform

class Func(object):
  def __new__(cls, *args, **kwargs):
    name = platform.system() + 'Func'
    instance = None
    try:
      m = __import__('functionality.' + name)
      m = getattr(m, name)
      m = getattr(m, name) 
      instance = object.__new__(m) #TODO: Evtl args und kwargs mitgeben?!?
    except (ImportError, AttributeError, TypeError):
      raise NotImplementedError("Not implemented for your system!")
    return instance

  def something(self, foo):
    raise NotImplementedError("Not implemented for your system!")
LinuxFunc.py

Code: Alles auswählen

import functionality.Func

class LinuxFunc(functionality.Func.Func):
  def something(self, foo):
    print "hi", foo

Angewandt wird das nun so:

Code: Alles auswählen

from functionality.Func import Func

f = Func()
f.something('Du da')
print f
Was haltet ihr von diesem Vorgehen?
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: Systemabhängig verschiedene Klassen instanzieren

Beitrag von Panke » So Jul 10, 2011 2:09 pm

Viel zu kompliziert. Kannst du nicht einfach die entsprechende Klasse abhängig vom System
in Func an einen Namen binden?

Code: Alles auswählen

#in func.py

if __system__ == "LINUX":
    import MyLinuxClass from func_linux
    MyClass = MyLinuxClass
elif ...

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Systemabhängig verschiedene Klassen instanzieren

Beitrag von Dirty Oerti » So Jul 10, 2011 2:57 pm

Kann ich dann - um mal bei deinem Beispiel zu bleiben - func.py importieren und einfach eine Instanz von (in diesem Fall) MyLinuxClass über MyClass() bekommen?
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: Systemabhängig verschiedene Klassen instanzieren

Beitrag von Panke » Mo Jul 11, 2011 6:23 pm

Ja. Habs gerade nochmal extra ausprobiert.

Benutzeravatar
Dirty Oerti
Beiträge: 2229
Registriert: Di Jul 08, 2008 5:05 pm
Wohnort: Thurndorf / Würzburg

Re: Systemabhängig verschiedene Klassen instanzieren

Beitrag von Dirty Oerti » Mo Jul 11, 2011 10:24 pm

Cool! :)
Das werde ich evtl übernehmen ... ich brauche ja außerdem sozusagen ein Singleton, wobei ich das auch anders lösen kann ... mal gucken ;)
Bei Fragen einfach an daniel[ät]proggen[Punkt]org
Ich helfe gerne! :)
----------
Wenn du ein Licht am Ende des Tunnels siehst, freu dich nicht zu früh! Es könnte ein Zug sein, der auf dich zukommt!
----
It said: "Install Win95 or better ..." So I installed Linux.

Panke
Beiträge: 70
Registriert: So Nov 14, 2010 10:47 am

Re: Systemabhängig verschiedene Klassen instanzieren

Beitrag von Panke » Mo Jul 11, 2011 11:36 pm

Ist Singleton nicht mittlerweile ein Anti-Pattern? In Python sieht man das imo eher selten.
Wenn dann würd ich ein Modul nehmen. Das sind im Grunde Singletons.

Antworten