Überprüfen der Parameter einer Funktion, wie?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
zacharias
User
Beiträge: 11
Registriert: Samstag 2. Juni 2007, 00:36

Hm, irgendwie hab ich zuwenig Zeichen, um den Titel aussagekräftiger zu machen, sei's drum...

Ich habe folgendes Problem:

Ich binde zur Laufzeit Module in ein, die gewisse Funktionen enthalten müssen, die wiederum über gewisse Parameter verfügen sollen:

Code: Alles auswählen

mything=__import__("somemodule")
try:
  getattr(mything,"mainfunction")
except:
  ...
Damit überprüfe ich, ob mything über mainfunction verfügt. Wie allerdings überprüfe ich, welche Parameter mainfunction hat? Nehmen wir an, es muss über die Parameter fullname und priority verfügen, bzw. im Modul selbst muss

Code: Alles auswählen

def mainfunction(fullname,priority)
definiert sein bzw. wie komme ich überhaupt drauf, was für Parameter eine Funktion hat, ohne sie vorher aufzurufen?

Ich habe mich mit dir() herumgespielt, aber nichts gefunden.
Zuletzt geändert von zacharias am Dienstag 3. November 2009, 19:40, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

zacharias hat geschrieben: definiert sein bzw. wie komme ich überhaupt drauf, was für Parameter eine Funktion hat, ohne sie vorher aufzurufen?
Meinst Du die Anzahl? Oder was genau willst Du wissen?

Generell kapiere ich nicht genau, wo das Problem liegt! Schnittstellen sollten doch bekannt sein - oder eben vorher definiert werden.
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

Gehen tut das. Ob das so sinnvoll ist, naja... :roll:

Code: Alles auswählen

In [14]: def mainfunction(fullname,priority):
   ....:     pass
   ....:

In [15]: mainfunction.func_code.co_argcount
Out[15]: 2

In [16]: mainfunction.func_code.co_varnames
Out[16]: ('fullname', 'priority')
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

zacharias hat geschrieben:

Code: Alles auswählen

try:
  getattr(mything,"mainfunction")
except:
  ...

Code: Alles auswählen

if not hasattr(mything, 'mainfunction'):
    ...
zacharias
User
Beiträge: 11
Registriert: Samstag 2. Juni 2007, 00:36

Hyperion: Sicher werden Schnittstellen definiert, nur will ich bei Laufzeit einzubindende Module so genau wie nur irgendmöglich im Vorhinein überprüfen.

Zap: Danke, das ist es, was ich dazu brauche.

snafu: Ebenfalls Dank.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Also ich würde sowas mit Dekoratoren machen...
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

In Python macht man sowas aber nicht!
Gewöhn dir so einen Stil auf keinen Fall an.

Edit: Gute Idee Leonidas!

P.S. in den Forumsregeln steht, man soll keinen Thread mit "solved" oder ähnlichem markieren.
http://wiki.python-forum.de/Forum/Regeln
BlackJack

Die Lösung von Zap ist auch implementierungsabhängig. Die Funktionen im `inspect`-Modul sind da sicher robuster.

Allerdings erschliesst sich mir auch die Intention nicht ganz. Es geht ja schon gegen die Pythonphilosophie auf Typen zu testen, aber Anzahl und Namen von Argumenten!? Argh!

Was ist denn mit Funktionen die sich richtig verhalten, aber andere Namen für die Argumente verwenden? Zum Beispiel weil man eine Funktion, die die Bedingungen sogar erfüllt, mit einem Dekorator zum Loggen von Aufrufen versehen hat. Oder man hat eine Funktion die gar nicht dafür vorgesehen war, aber trotzdem das gewünschte Verhalten aufweist, aber eben nicht die Namen. Und was ist mit *args und **kwargs? Warum sollte man das verbieten wollen!?
zacharias
User
Beiträge: 11
Registriert: Samstag 2. Juni 2007, 00:36

Weil die dynamisch einzubindenden Module de facto Eingaben darstellen, Eingaben eines Programms auf Gültigkeit zu prüfen sind, und eine Uniformität besagter Module in bestimmten Bereichen einfach die Wartbarkeit des Projekts extrem verbessert.

Danke für die Hilfe, Leuteln :)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Da würde ich mir dann aber eher ``zope.interface`` angucken, statt das Rad neu zu erfinden.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
zacharias
User
Beiträge: 11
Registriert: Samstag 2. Juni 2007, 00:36

Das wär mit Kanonen auf Spatzen schießen, denn - das war's schon. Mehr brauch ich nicht. Ich will nur das eine oder andere Modul einbinden, und schauen, ob die gewünschte Funktion darin vorhanden ist. Des woar's, fertig.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ist

Code: Alles auswählen

try:
    module.func
except AttributeError:
    print "Function not found"
oder

Code: Alles auswählen

try:
    module.__getattribute__(func_name)
except AttributeError:
    print "%s not found" % func_name
was du willst?
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@cofi:

Warum so kompliziert? Auch hier sollte ein `if hasattr(module, 'func_name'):` genügen, um ggf. auf die gewünschte Funktionalität zuzugreifen.
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

snafu hat geschrieben:@cofi:

Warum so kompliziert? Auch hier sollte ein `if hasattr(module, 'func_name'):` genügen, um ggf. auf die gewünschte Funktionalität zuzugreifen.
Der Unterschied ist: Bei deiner Variante wird jedes Mal geprüft, ob der Name vorhanden ist (und das Ganze dann noch einmal beim eigentlichen Zugriff). Geht man davon aus, daß er das in der Mehrzahl der Fälle ist, verlangsamst du den Zugriff unnötig. Cofis Variante schlägt dagegen nur an, wenn er *nicht* vorhanden ist.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nunja, das liesse sich auch durch `not hasattr` und eine entsprechende Behandlung ersetzen, insofern ist das nicht "schlechter". Im Prinzip ist das aber recht egal.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

cofi hat geschrieben:Nunja, das liesse sich auch durch `not hasattr` und eine entsprechende Behandlung ersetzen, insofern ist das nicht "schlechter". Im Prinzip ist das aber recht egal.
Finde deine Variante besser. Es heißt ja nicht umsonst
Explicit is better than implicit.
;)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Hmm dann aber per `getattr` ;)
Antworten