Seite 1 von 1

Überprüfen der Parameter einer Funktion, wie?

Verfasst: Dienstag 3. November 2009, 14:34
von zacharias
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.

Re: Überprüfen der Parameter einer Funktion, wie?

Verfasst: Dienstag 3. November 2009, 14:43
von Hyperion
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.

Verfasst: Dienstag 3. November 2009, 14:53
von Zap
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')

Re: Überprüfen der Parameter einer Funktion, wie?

Verfasst: Dienstag 3. November 2009, 18:19
von snafu
zacharias hat geschrieben:

Code: Alles auswählen

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

Code: Alles auswählen

if not hasattr(mything, 'mainfunction'):
    ...

Verfasst: Dienstag 3. November 2009, 19:40
von zacharias
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.

Verfasst: Dienstag 3. November 2009, 19:44
von Leonidas
Also ich würde sowas mit Dekoratoren machen...

Verfasst: Dienstag 3. November 2009, 19:45
von ms4py
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

Verfasst: Dienstag 3. November 2009, 20:34
von 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!?

Verfasst: Donnerstag 5. November 2009, 14:27
von zacharias
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 :)

Verfasst: Donnerstag 5. November 2009, 14:31
von Leonidas
Da würde ich mir dann aber eher ``zope.interface`` angucken, statt das Rad neu zu erfinden.

Verfasst: Donnerstag 5. November 2009, 14:37
von zacharias
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.

Verfasst: Donnerstag 5. November 2009, 20:03
von cofi
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?

Verfasst: Donnerstag 5. November 2009, 20:59
von snafu
@cofi:

Warum so kompliziert? Auch hier sollte ein `if hasattr(module, 'func_name'):` genügen, um ggf. auf die gewünschte Funktionalität zuzugreifen.

Verfasst: Donnerstag 5. November 2009, 21:17
von Pekh
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.

Verfasst: Donnerstag 5. November 2009, 21:25
von cofi
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.

Verfasst: Donnerstag 5. November 2009, 21:29
von ms4py
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.
;)

Verfasst: Donnerstag 5. November 2009, 21:42
von cofi
Hmm dann aber per `getattr` ;)