2015-01-13 4 views
3

Есть ли способ определить функцию, которая будет глобальной изнутри класса (или изнутри другой функции, по сути)? Что-то похожее на определение глобальной переменной.Как определить глобальную функцию в Python?

+4

Зачем вам это вообще нужно? –

+1

Вы можете назначить глобальную переменную функцию, определенную локально, если это то, что вы имеете в виду. – khelwood

+0

Я полагаю, вы могли бы использовать 'global foo' и' def'/'class foo' для этого ... – Kevin

ответ

13

Функции добавляются в текущее пространство имен, как и любое другое имя. Это означает, что вы можете использовать ключевое слово global внутри функции или метода:

def create_global_function(): 
    global foo 
    def foo(): return 'bar' 

То же самое относится к классу тела или метода:

class ClassWithGlobalFunction: 
    global spam 
    def spam(): return 'eggs' 

    def method(self): 
     global monty 
     def monty(): return 'python' 

с той разницей, что spam будет определяться сразу же ТОП- при импорте.

Как и все виды использования global, вы, вероятно, захотите переосмыслить проблему и найти другой способ ее решения. Вы могли бы вернуть функцию, созданную таким образом, например.

Демо:

>>> def create_global_function(): 
...  global foo 
...  def foo(): return 'bar' 
... 
>>> foo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'foo' is not defined 
>>> create_global_function() 
>>> foo 
<function foo at 0x102a0c7d0> 
>>> foo() 
'bar' 
>>> class ClassWithGlobalFunction: 
...  global spam 
...  def spam(): return 'eggs' 
...  def method(self): 
...   global monty 
...   def monty(): return 'python' 
... 
>>> spam 
<function spam at 0x102a0cb18> 
>>> spam() 
'eggs' 
>>> monty 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'monty' is not defined 
>>> ClassWithGlobalFunction().method() 
>>> monty() 
'python' 
+1

@flamenco: Я действительно предполагал, что OP означает * из метода в классе *. Не из самого класса класса. В любом случае то же самое относится и к использованию оператора в классе определения класса, но я бы скорее сказал, почему вы хотите сделать это *. –

+1

@flamenco: Код в моем предыдущем ответе четко объясняет, что вы не являетесь оберточной функцией. –

+2

@flamenco: изменяющиеся глобальные значения не являются потокобезопасными и могут легко привести к * очень * запутанному коду. Изменение функций таким образом, тем более. –

7

Вы можете использовать глобальные объявить глобальную функцию из класса. Проблема с этим заключается в том, что вы не можете использовать его с областью класса, чтобы он мог объявить его вне класса.

class X: 
    global d 
    def d(): 
    print 'I might be defined in a class, but I\'m global' 

>> X.d 

    Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    AttributeError: 'X' object has no attribute 'd' 

>> d() 

I might be defined in a class, but I'm global 
+2

, пожалуйста, объясните downvote –

+2

Так что я не размещал более 4 раз в stackoverflow. Большая сделка? Ответ, тем не менее, объясняет вам, как это сделать, и родная проблема, связанная с вопросом. –

+0

вне класса походит на нарушение принципа инкапсуляции OOPS. Однако метод, объявленный как глобальный, может быть вызван другими методами внутри класса, но на любом объекте класса. В этом случае «глобальное» слово действительно не имеет смысла. Его более локальный (закрытый в java-терминах), чем глобальный, поскольку только методы класса могут получить доступ к этому методу, объявленному как глобальный. Все это означает, что это условный сценарий. Я считаю, что этот аспект нуждается в исправлении в python – Rags

Смежные вопросы