Is there a way to define a function to be global from within a class( or from within another function, as matter of fact)? Something similar to defining a global variable.
Functions are added to the current namespace like any other name would be added. That means you can use the global keyword inside a function or method:
def create_global_function():
global foo
def foo(): return 'bar'
The same applies to a class body or method:
class ClassWithGlobalFunction:
global spam
def spam(): return 'eggs'
def method(self):
global monty
def monty(): return 'python'
with the difference that spam will be defined immediately as top-level class bodies are executed on import.
Like all uses of global you probably want to rethink the problem and find another way to solve it. You could return the function so created instead, for example.
Demo:
>>> 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'
You can use global to declare a global function from within a class. The problem with doing that is you can not use it with a class scope so might as well declare it outside the class.
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
I found a case where global does not have the desired effect: inside .pdbrc file. If you define functions in .pdbrc they will only be available from the stack frame from which pdb.set_trace() was called.
However, you can add a function globally, so that it will be available in all stack frames, by using an alternative syntax:
def cow(): print("I'm a cow")
globals()['cow']=cow
I've tested that it also works in place of the global keyword in at least the simplest case:
def fish():
def cow():
print("I'm a cow")
globals()['cow']=cow
Despite being more verbose, I thought it was worth sharing this alternative syntax. I have not tested it extensively so I can't comment on its limitations vs using the global keyword.
Related
The following code
1 def foo():
2 def bar():
3 return 'blah'
4 def baz():
5 eval('bar')
6 baz()
7 foo()
causes a NameError -- the entire error message is
Traceback (most recent call last):
File "main.py", line 7, in <module>
foo()
File "main.py", line 6, in foo
baz()
File "main.py", line 5, in baz
eval('bar')
File "<string>", line 1, in <module>
NameError: name 'bar' is not defined
On the other hand, the following, almost identical code,
1 def foo():
2 def bar():
3 return 'blah'
4 def baz():
5 print(bar); eval('bar')
6 baz()
7 foo()
does not cause any error. In fact, it prints <function foo.<locals>.bar at 0x7fd5fdb24af0>.
So I was wondering why, in the first piece of code, is the variable named bar not defined/available in line 5. And why does printing bar before calling eval('bar') fix this issue. From my understanding bar should be a local variable of function foo, so it should be accessible from function foo.baz. Is it something about eval that screws this up that printing beforehand fixes?
>>> help(eval)
Help on built-in function eval in module builtins:
eval(source, globals=None, locals=None, /)
Evaluate the given source in the context of globals and locals.
The source may be a string representing a Python expression
or a code object as returned by compile().
The globals must be a dictionary and locals can be any mapping,
defaulting to the current globals and locals.
If only globals is given, locals defaults to it.
In your first example bar is not in local scope but in your second example it is in local because the statement print(bar) forces a scope resolution lookup before eval executes. (In neither example is bar in global scope.)
There are a couple of options you can use to pull bar into your desired scope:
# option 1: nonlocal (better)
def foo():
def bar():
return 'blah'
def baz():
nonlocal bar
eval('bar');
baz()
foo()
# option 2: pass a copy of actual scope to eval (less better)
def foo():
def bar():
return 'blah'
def baz():
eval('bar', None, local_scope); # or eval('bar', local_scope)
local_scope = locals()
baz()
foo()
class Difference:
def __init__(self, a):
self.__elements = a
def computeDifference(self):
b = min(self.__elements)
c = max(self.__elements)
result = abs(b-c)
self.maximumDifference = result
_ = input()
a = [int(e) for e in input().split(' ')]
d = Difference(a)
d.computeDifference()
print(d.maximumDifference)
I am unable to understand how I was able to call maximumdifference, which is a variable inside the computeDifference function, Which is inside the Difference class?
how I was able to call maximumdifference, which is a variable inside the computeDifference function, Which is inside the Difference class?
I think the core of your question comes from a slight misunderstanding: self.maximumDifference is a field in the class Difference. This field was created on-the-fly when the computeDifference function was called.
As another example:
... def foo(self):
... self.bar = "hi"
...
>>> a = A()
>>> a.bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'bar'
>>> a.foo()
>>> a.bar
'hi'
Here we can see how the bar attribute does not exist until after the foo function was run. If you're familiar with other languages, this may be surprising behavior --- many other languages require that class attributes/fields are fixed/specified in the class or constructor, but Python allows adding new fields on-the-fly.
This question already has an answer here:
How to call a compiled function body?
(1 answer)
Closed 2 years ago.
Is there a way I could access a function that is nested inside another function. For example, I have this block of code right here. For example, I did f().s() but it did not work:
def f():
def s():
print(13)
Yes, you can:
def f():
def s():
print(13)
return s
Then you can call:
>>> f()()
13
Or if you want to have f().s():
def f():
class S:
def s():
print(13)
return S
You need to specify that the second function is a global var, then you'd need to call the first function in order for Python interpreter to create that second function.
See below;
>>> def foo():
... global bar
... def bar():
... print("Hello world!")
...
>>> bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'bar' is not defined
>>> foo()
>>> bar()
Hello world!
>>>
you certainly could do something
def f():
def s():
print("S")
return s
f()()
you could also expose them in an internal dict
def f(cmd):
return {"s": lambda: do_something_s,"y": lambda: do_something_y}.get(cmd,lambda:invalid_cmd)()
then use f("s") or f("y")
none of these are likely to be the correct solution to what you are actually trying to achieve ...
I am new to Python. I am trying to create a class which only allows to objects to be created. I am using a private variable instance to keep track of count .
My Code -
class s:
__instance=2
if s.__instance<2:
def __init__(self,x):
s._instance = x
s._instance = s._instance+1
print(s._instance)
a=s(5)
When i run the code i got -
"C:\Users\PIYU\AppData\Local\Programs\Python\Python36\python.exe"
"C:/Users/PIYU/PycharmProjects/PythonProgram/singleton.py"
Traceback (most recent call last):
File "C:/Users/PIYU/PycharmProjects/PythonProgram/singleton.py", line 1, in <module>
class s:
File "C:/Users/PIYU/PycharmProjects/PythonProgram/singleton.py", line 4, in s
if s.__instance<2:
NameError: name 's' is not defined
The error is because you are trying to reference s in it's own definition, before it is actually defined. I would try using that condition in __init__ instead of before it.
In Python, class is an executable statement that creates a new class class object and bind it to the class name in the enclosing scope. Until the whole statement has been executed (IOW until the end of the class statement block), the class object doesn't exist and the name is not defined.
To make things clearer, this:
class Foo(object):
bar = 42
def foo(self):
print "foo"
is actually only syntactic sugar for
def foo(self):
print "foo"
Foo = type("Foo", (object,), {"foo": foo, "bar": 42})
del foo # remove the name from current scope
I'm trying clean implement of Objective-C's category in Python, and found this answer to similar question of mine. I copied the code below:
categories.py
class category(object):
def __init__(self, mainModule, override = True):
self.mainModule = mainModule
self.override = override
def __call__(self, function):
if self.override or function.__name__ not in dir(self.mainModule):
setattr(self.mainModule, function.__name__, function)
But I do not want to waste namespace.
By using this `categories', there remains a variable as NoneType object like below:
>>> from categories import category
>>> class Test(object):
... pass
...
>>> #category(Test)
... def foobar(self, msg):
... print msg
...
>>> test = Test()
>>> test.foobar('hello world')
hello world
>>> type(foobar)
<type 'NoneType'>
>>>
I want it to be like below
>>> from categories import category
>>> class Test(object):
... pass
...
>>> #category(Test)
... def foobar(self, msg):
... print msg
...
>>> test = Test()
>>> test.foobar('hello world')
hello world
>>> type(foobar)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'foobar' is not defined
>>>
Is there anyway to delete it automatically like below?
def __call__(self, function):
if self.override or function.__name__ not in dir(self.mainModule):
setattr(self.mainModule, function.__name__, function)
del(somewhere.function.__name__)
I found that sys._getframe give me some useful information. But I couldn't make it by myself.
No, there's no way to automatically do that. You would have to manually delete the name afterwards. category here is a decorator, which means that
#category(Test)
def f():
...
is the same as
def f():
...
f = category(Test)(f)
Even if, from inside category, you could delete the name in the outer scope, it wouldn't be enough, because that name is rebound after the decorator executes.
The code that you linked to borders on an abuse of the decorator syntax. Decorators are meant to provide a way to modify or extend the function they decorate, but that code relies on side-effects of the decorator (namely, assigning the function as a method of a class), and then discards the function. But it can only "discard" it by returning None, so None remains bound to the function's name, as you saw.
I would recommend you follow the advice of the highest-voted answer on that question, and simply assign new methods to your classes. There is no real need for an "infrastructure" like categories in Python, because you can just directly add new methods to existing classes whenever you want.
While I completely agree with what BrenBarn said, you could split the function removal into a later step. The problem is that after the decorator executed, the variable is reassigned. So you cannot perform the removal within the decorator itself.
You could however remember the functions and remove them from the module at a later point.
class category(object):
functions = []
def __init__(self, mainModule, override = True):
self.mainModule = mainModule
self.override = override
def __call__(self, function):
if self.override or function.__name__ not in dir(self.mainModule):
setattr(self.mainModule, function.__name__, function)
self.functions.append((inspect.getmodule(function), function.__name__))
return self.dummy
#staticmethod
def dummy():
pass
#classmethod
def cleanUp(cls):
for module, name in cls.functions:
if hasattr(module, name) and getattr(module, name) == cls.dummy:
delattr(module, name)
cls.functions = []
This category type will remember the functions it decorates and stores the names and modules they belong to for a later cleanup. The decorator also returns a special dummy function so that the cleanup can ensure that the variable was not reassigned later.
>>> class Test(object): pass
>>> #category(Test)
def foobar(self, msg):
print(msg)
>>> #category(Test)
def hello_world(self):
print('Hello world')
>>> test = Test()
>>> test.foobar('xy')
xy
>>> test.hello_world()
Hello world
>>> type(foobar)
<class 'function'>
>>> type(hello_world)
<class 'function'>
>>> category.cleanUp()
>>> type(foobar)
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
type(foobar)
NameError: name 'foobar' is not defined
>>> type(hello_world)
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
type(hello_world)
NameError: name 'hello_world' is not defined