Let's say I want to rename a function like "print" into "bark". Is there a way to do that?
I found information on how to apply another name to a library, but that's it. And don't ask about the question, the "bark" idea is just an example. I remember you can do something like that in C# and wonder if Python is an exception.
You can change the "name" of the function assigning it to an other variable, since in Python functions are objects.
>>> def foo(): pass
>>> foo
<function foo at 0x0000021C6B537E20>
>>> bar = foo
>>> bar
<function foo at 0x0000021C6B537E20> # Functions gets named with the name given by def, so assigning it to bar doesn't really change its name
So you just have to do this:
bar = foo # That's it
If you have the doubt that this may be a non-working way in some language, why don't you simply try? Open your Python Launcher, then insert this commands:
>>> myFunction = quit
>>> myFunction()
If the window collapses then you have the prove that this works with Python.
I found information on how to apply another name to a library
Yes, in this case you would have to do this:
from myModule import foo as bar
You can just write
bark = print
bark('Hello World')
Related
Here:
from os.path import exists as foo
print foo.__name__
we get: 'exists'.
Why not 'foo'? Which attribute would give 'foo'?
You can view import foo as bar as just an assignment. You would not expect a function to change its __name__ attribute when you assign another name to the function.
>>> def foo(): pass
>>>
>>> foo.__name__
'foo'
>>> bar = foo
>>> bar.__name__
'foo'
Thanks. What attribute of the variable bar would return the string 'bar' then?
There is no such attribute. Names (bar) refer to values (the function object) unidirectionally.
The __name__ attribute of a function is set as the name the function was defined with using the
def ... syntax. That's why you don't get a meaningful __name__ attribute if you define an anonymous function and assign the name foo after it has been created.
>>> foo = lambda: None
>>> foo.__name__
'<lambda>'
Importing an object just binds a new variable, and all that adding as newname does is let you pick an alternative name to use for the variable in the current namespace.
The __name__ attribute on an object says nothing about the name it is currently bound to, you can have any number of variables as well as containers such as lists or dictionaries pointing to the same object, after all:
def foo(): pass
bar = foo
spam = foo
list_of_functions = [foo]
dictionary_of_functions = {'monty': foo, 'python': foo}
The above created 4 additional references to the function object; you can't have foo.__name__ reflect all of those, and the references in list_of_functions and dictionary_of_functions do not (directly) have names.
Since import foo, import bar as foo, from module import foo and from module import bar as foo all just set the name foo in the current module, they are treated the exact same way as other assignments. You could import the function more than once, under different names, too.
Instead, the __name__ value of a function is set to name it was defined with in the def <name>(...): statement. It is a debugging aid, at most. It is used in tracebacks, for example, to make it easier to identify lines of code shown in the traceback. You'd only set the __name__ to something else if that would help identify the location better. (Note: in Python 3, there is also the __qualname_ attribute, which is used instead of __name__ as it includes more information on where the function is defined when nested or defined on a class).
The as is syntactical sugar in the file/session of the import, while the __name__ attribute is part of the function object.
This question already has answers here:
Can the python interpreter fail on redeclared functions?
(2 answers)
Closed 8 years ago.
For example:
def foo():
print 'first foo'
def foo():
print 'second foo'
foo()
silently produces: second foo
Today I copy/pasted a function definition in the same file and changed a few lines in the body of second definition but forgot to change the function name itself. I scratched my head for a long time looking at the output and it took me a while to figure it out.
How to force the interpreter throw at least a warning at redefinition of a function? Thanks in advance.
How about using pylint?
pylint your_code.py
Let your_code.py be
1 def dup():
2 print 'a'
3 def dup():
4 print 'a'
5
6 dup()
pylint shows
C: 1,0: Missing docstring
C: 1,0:dup: Missing docstring
E: 3,0:dup: function already defined line 1 <--- HERE!!!!
C: 3,0:dup: Missing docstring
...
If you are using Pydev, You can find duplication interactively.
When mouseover the second dup, It says Duplicated signature: dup.
It is one of features of Python. Functions are values just as integers, so you can pass them around and rebind to names, just as you would in C++ using function pointers.
Look at this code:
def foo(): # we define function and bind func object to name 'foo'
print "this if foo"
foo() # >>>this if foo
bar = foo # we bind name 'bar' to the same function object
def foo(): # new function object is created and bound to foo
print "this is new foo"
foo() # foo now points to new object
# >>>this is new foo
bar() # but old function object is still unmodified:
# >>>this if foo
Thus interpreter works fine. In fact it is common to redefine functions when you are working with interactive interpreter, until you get it right. Or when you use decorators.
If you want to be warned about redefining something in python, you can use 'lint' tools, like pylint (see function-redefined (E0102))
I think it is a similar behaviour for what happens with variables (called identifiers):
In [4]: a = 2
In [5]: a = 3
In [6]: a
Out[6]: 3
you don't see the interpreter whining about a being redefined.
EDIT Somebody commented below and I think it might help clarifying my answer:
[this is due to] function objects are not treated differently from other objects, and
that names defined via def aren't treated differently from names
defined via other means
See the language reference about def being a reserved identifier.
You need to know python philosophy of object. Everything in python is object. When you create a function, you actually create object of class function and name it as your function name.
When you re-define it you simply replace old object with new one simple as creating new variable of same name.
e.g.
>>> a=10
>>> print a
10
>>> a=20
>>> print a
20
same way you can check class of the function.
>>> def a():
... pass
...
>>> a.__class__
<type 'function'>
which indicates your function is actually a object or variable that can be replaced with any other object variable of same class.
Well, you could check if it exists like this
def foo():
pass
def check_foo(variable_dict):
if 'foo' in variable_dict:
print('Function foo already exists!')
else:
print('Function foo does not exist..')
>>> check_foo()
True
>>> del foo
>>> check_foo(locals())
False
In python I can create a class without class statement:
MyClass = type('X', (object,), dict(a=1))
Is there a way to create a function without 'def'?
Thats as far as i got...
d={} # func from string
exec'''\
def synthetics(s):
return s*s+1
''' in d
>>> d.keys()
['__builtins__', 'synthetics']
>>> d['synthetics']
<function synthetics at 0x00D09E70>
>>> foo = d['synthetics']
>>> foo(1)
2
Technically, yes, this is possible. The type of a function is, like all other types, a constructor for instances of that type:
FunctionType = type(lambda: 0)
help(FunctionType)
As you can see from the help, you need at minimum code and globals. The former is a compiled bytecode object; the latter is a dictionary.
To make the code object, you can use the code type's constructor:
CodeType = type((lambda: 0).func_code)
help(CodeType)
The help says this is "not for the faint of heart" and that's true. You need to pass bytecode and a bunch of other stuff to this constructor. So the easiest way to get a code object is from another function, or using the compile() function. But it is technically possible to generate code objects completely synthetically if you understand Python bytecode well enough. (I have done this, on a very limited basis, to construct signature-preserving wrapper functions for use in decorators.)
PS -- FunctionType and CodeType are also available via the types module.
There might be a more direct way than the following, but here's a full-blown function without def. First, use a trivial lambda expression to get a function object:
>>> func = lambda: None
Then, compile some source code to get a code object and use that to replace the lambda's code:
>>> func.__code__ = compile("print('Hello, world!')", "<no file>", "exec")
>>> func()
Hello, world!
EDIT 2 : since so many people are crying against the bad design this usecase can reveal. Readers of these question and answers should think twice before using it
I've trying to set a variable (not property) by it's name in Python :
foo = 'bar'
thefunctionimlookingfor('foo', 'baz')
print foot #should print baz
PS : the function to access a variable by its name (without eval) would be a plus !
EDIT : I do know dictionary exists, this kind of usage is discouraged, I've choose to use it for a very specific purpose (config file modification according to environment), that will let my code easier to read.
When you want variably-named variables, it's time to use a dictionary:
data = {}
foo = 'bar'
data[foo] = 'baz'
print data['bar']
Dynamically setting variables in the local scope is not possible in Python 2.x without using exec, and not possible at all in Python 3.x. You can change the global scope by modifying the dictionary returned by globals(), but you actually shouldn't. Simply use your own dictionary instead.
You can do something like:
def thefunctionimlookingfor(a, b):
globals()[a] = b
Usage:
>>> foo
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'q' is not defined
>>> thefunctionimlookingfor('foo', 'bar')
>>> foo
'bar'
But this is a terrible idea, as others have mentioned. Namespaces are a useful concept. Consider a redesign.
At the module level you can use setattr on the current module, which you can get from sys.modules:
setattr(sys.modules[__name__], 'name', 'value')
The locals() function returns a dictionary filled with the local variables.
locals()['foo'] = 'baz'
Are you looking for functions like these? They allow modifying the local namespace you happen to be in.
import sys
def get_var(name):
return sys._getframe(1).f_locals[name]
def set_var(name, value):
sys._getframe(1).f_locals[name] = value
def del_var(name):
del sys._getframe(1).f_locals[name]
I have a Python module with a function in it:
== bar.py ==
def foo(): pass
== EOF ==
And then I import it into the global namespace like so:
from bar import *
So now the function foo is available to me. If I print it:
print foo
The interpreter happily tells me:
<function foo at 0xb7eef10c>
Is there a way for me to find out that function foo came from module bar at this point?
foo.__module__ should return bar
If you need more info, you can get it from sys.modules['bar'], its __file__ and __package__ attributes may be interesting.
Try this:
help(foo.func_name)
Instead of
from bar import *
use
from bar import foo
Using the from ... import * syntax is a bad programming style precisely because it makes it hard to know where elements of your namespace come from.
If you have IPython, you can also use ?:
In[16]: runfile?
Signature: runfile(filename, args=None, wdir=None, is_module=False, global_vars=None)
Docstring:
Run filename
args: command line arguments (string)
wdir: working directory
File: /Applications/PyCharm.app/Contents/helpers/pydev/_pydev_bundle/pydev_umd.py
Type: function
Compare with __module__:
In[17]: runfile.__module__
Out[17]: '_pydev_bundle.pydev_umd'