2010-10-15 4 views
7

Ist es möglich, Funktionen in Python zu deklarieren und sie später oder in einer separaten Datei zu definieren?Funktionserklärung in Python, um einen lesbaren und sauberen Code zu haben?

Ich habe einige Code wie:

class tata: 
    def method1(self): 
     def func1(): 
     # This local function will be only used in method1, so there is no use to 
     # define it outside. 
     # Some code for func1. 
     # Some code for method1. 

Das Problem ist, dass der Code chaotisch und schwierig wird, zu lesen. Also frage ich mich, ob es zum Beispiel möglich ist, func1 in method1 zu deklarieren und später zu definieren?

+0

Wenn die Funktion func1() nur für method1() relevant ist und die innere Methode zu einem Problem für Sie wird, ist dies ein Hinweis darauf, dass es sich eigentlich um eine separate Klasse handeln sollte. –

Antwort

6

Klar, kein Problem:

foo.py:

def func1(): 
    pass 

script.py:

import foo 
class tata: 
    def method1(self): 
     func1=foo.func1 
+0

Schönes Denken! Die Idee einer lokalen Funktion besteht jedoch darin, diese Funktion nur innerhalb des inneren Bereichs nutzbar zu machen. Also, was ist der Sinn der Definition des neuen 'func1' in' method1'? Wäre nicht einfacher zu tun: 'von foo Import func1' und benutze es. – banx

+0

@banx: Alex Martellis Antwort hier (http: // stackoverflow.com/questions/1744258/is-import-modul-better-coding-style-als-von-modul-import-funktion) überredete mich, 'from foo import func1' komplett zu vermeiden. – unutbu

+0

@banx: Ja, die Definition von 'func1' in' method1' zu setzen, macht es zumindest halb-privat, obwohl ich es nicht an einem unternehmungslustigen Bytecode-Hacker vorbeibringen würde (http://stackoverflow.com/questions/3908335/python -function-local-name-binding-from-a-outer-scope/3913185 # 3913185), um einen Weg zu finden, was Sie denken, ist privat nicht so privat. – unutbu

2

Die innere Definition erstellt einen separaten Namen im inneren Bereich. Es überschattet alles, was Sie später mit dem gleichen Namen definieren. Wenn Sie die Funktion später definieren möchten, tun Sie dies einfach. Der Name wird nur geprüft, wenn er tatsächlich verwendet wird.

def foo(): 
    print 'foo' 
    bar() 

def bar(): 
    print 'bar' 

foo() 
3

Ich denke, was Sie wollen, ist die Funktion innerhalb method1 importieren , z.B

def method1(...): 
    from module_where_func1_is_defined import func1 
    # do stuff 
    something = func1(stuff, more_stuff) 
    # do more stuff 

Python-Module sind grundsätzlich nur Dateien; Solange sich die Datei module_where_func1_is_defined.py im selben Verzeichnis wie Ihr Skript befindet, kann method1 diese Datei importieren.

Wenn Sie in der Lage sein, die Art und Weise method1 Werke zu gestalten und sie auch mehr machen auch deutlich, dass es verwendet func1, können Sie func1-method1 als Standard-Parameter übergeben:

import other_module 

# various codes 

def method1(other_args, func=other_module.func1) 
    # do stuff 
    something = func(stuff, more_stuff) 
    # do more stuff 
2

Wenn func1 () muss mit allem umgehen, was im Bereich von method1() enthalten ist, du solltest die Definition von func1() dort lassen. Sie müssen func1 haben() erhalten alle relevanten Daten als Parameter, wenn sie nicht im Rahmen der method1() definiert ist

+0

+1 Da geschachtelte Funktionen direkt auf Namen von ihrem enthaltenden Bereich zugreifen, ist eine wichtige Idiom in Python. Die aktuellen Scoping-Regeln sind sehr mächtig und durchdacht - siehe [PEP 227 - Statisch verschachtelte Bereiche (ttp: //www.python.org/dev/peps/pep-0227/), die in Python 2.1 eingeführt wurden. Das Setzen von Definitionen in eine separate Datei würde dies derzeit verhindern, es sei denn, es wurde irgendwie umgegangen. – martineau

0

Sie Methoden erstellen können danach

 

class Something(object): 
    def test1(self): 
    pass 

def dummy(self): 
    print "ok", self 

Something.test1 = dummy 

aber es ist nicht möglich, eine anonyme haben Funktion (na ja, es gibt Lambda-Ausdrücke, aber Sie können keine Aussagen dort haben), so haben Sie einen temporären Namen bieten

vielleicht möchten Sie Dekorateure verwenden, um es besser lesbar zu machen:

 
def define(cls, name): 
    def decor(f): 
    setattr(cls, name, f) 
    return decor 


class Something(object): 
    def test1(self): 
    pass 

@define(Something, "test1") 
def dummy(self): 
    print "ok", self 

Dieser Code sollte besser lesbar sein. Es wird immer noch Dummy verschmutzen, aber initialisiere es mit Null.

Verwandte Themen