2016-05-23 6 views
-1

Im folgenden Code scheint func2 die __globals__func1 + auch die Symbole von contextlib zu haben. Kann jemand ausarbeiten, wie diese globals Verschmelzung funktioniert? IE, fusioniert es __dict__ 's aller Module bei der Definition der Funktion beteiligt? Was passiert auch, wenn es einen Namenskonflikt gibt?"__globals__" wird zusammengeführt, wenn Dekoratoren verwendet werden?

import contextlib 

def func1(): 
    pass 

@contextlib.contextmanager 
def func2(args): 
    pass 


globals1 = set(func1.__globals__.keys()) 
globals2 = set(func2.__globals__.keys()) 

globals2.difference(globals1)  

{'GeneratorContextManager', 
'__all__', 
'__file__', 
'closing', 
'contextmanager', 
'nested', 
'warn', 
'wraps'} 

Python Mit 2.7.10

+0

Was macht Sie denken, dass es beides hat? – BrenBarn

+0

weil, wenn ich Satz Unterschied von zwei Mengen von __globals__ nehme ich Symbole aus 'contextlib.py' in der zweiten, aktualisierte Frage –

+2

Das zeigt nur, dass' func1 .__ globals__' nicht diese Kontextlib-Namen hat; es zeigt nicht, dass 'func2 .__ globals__' *' 'func1' 'hat (und tatsächlich nicht). – BrenBarn

Antwort

3

Jedes Funktionsobjekt wird __globals__ gibt einen Verweis auf den globalen Namensraum des Moduls, wo die Funktion definiert wurde.

In Ihrem Beispiel ist func1 in Ihrem Modul definiert und hat die Globalen dieses Moduls. Sie haben func2 in Ihrem Modul definiert, aber der contextmanager Dekorator wickelt Ihre Funktion mit einer anderen Funktion ab. Diese Wrapperfunktion ist in contextlib definiert. Wenn also der Decorator func2 durch die Wrapped-Version ersetzt, hat die resultierende Funktion die Globalen Werte contextlib. Es hat nicht haben die Globals Ihres Moduls.

Die Wrapped-Funktion behält jedoch einen Verweis auf Ihre ursprüngliche Funktion, die immer noch die Globals Ihres eigenen Moduls enthält. In Ihrem Beispiel kann dies über func2.__closure__[0].cell_contents gesehen werden:

# func1 is not in func2's globals 
>>> func2.__globals__['func1'] 
Traceback (most recent call last): 
    File "<pyshell#6>", line 1, in <module> 
    func2.__globals__['func1'] 
KeyError: u'func1' 

# func1 is in the globals of the internally-stored wrapped version of func2 
>>> func2.__closure__[0].cell_contents.__globals__['func1'] 
<function func1 at 0x0000000002B2B358> 
Verwandte Themen