I have made a function named 'function' as below.
>>> def function():
return 'hello world'
>>> function
<function function at 0x7fac99db3048> #this is the output
What is this output exactly? It's specific name? And it's significance?
I know it gives info about memory location. But I need more information about this output.
Do the higher-order function return similar data while they are returning function?
In python function is an object and thus when you call function it returns you the memory address. The higher-order functions behave the same way. However there some differences:
def a():
print("Hello, World!")
def b():
return a
>>> a
<function a at 0x7f8bd15ce668>
>>> b
<function b at 0x7f8bd15ce6e0>
c = b
>>>c
<function b at 0x7f8bd15ce6e0>
c = b()
<function a at 0x7f8bd15ce668>
Note what the function c returns in different situations.
In order to call the function, you need to call it with (). Without that you are seeing reference to the function function stored at 0x7fac99db3048. You may also store it in another variable as:
>>> my_new = function # store function object in different variable
>>> function
<function function at 0x10502bc80>
# ^ memory address of my system
>>> my_new
<function function at 0x10502bc80>
# ^ same as above
>>> my_new() # performs same task
'hello world'
Let's see the content displayed for another function with name other than function:
>>> def hello_world():
... print 'hello world'
...
>>> hello_world
# v Name of function
<function hello_world at 0x105027758>
# ^ says object of type 'function'|^- memory address of function
# (for eg: for class says 'class')|
Related
how to call a function from a function object
a = fun_name
print(a)
like from this function object that I get how can I call the original function only from using this function object
<function fun_name at 0x00000265C9B0E320>
You just call the object, since it's just a function object, not really but it refers to it, example:
def a():
return 'a'
b = a
print(b())
You can call the original function like a() in this case.
As an example
def Test():
Function = 'one'
print(Function)
How does one go about doing that?
At the moment I get
NameError: name 'Function' is not defined
You can't do that. Function is only defined inside the Test() method.
If you want to, you should make the method return the string as follows:
def Test():
Function = 'one'
return Function
a = Test()
print(a)
The variable is out of the scope of that function. Either call that function or in the worst case you can use global keyword too.
Way 1 (better option):
def Test():
Function = 'one'
return Function
#If you print Function now, you will get the name error!
print(Function)
>>> NameError: name 'Function' is not defined
# If you call the function that works!!
print (Test())
>>> one
Way 2 (worse one):
>>> Function=''
>>> def Test():
global Function
Function = 'one'
>>> print(Test())
None
>>> print(Function)
one
>>>
[The code in the original version was badly messed up. Even after I fixed the code, several highly confusing typos remained in the post. I believe I finally fixed all of them too. Profuse apologies.]
The two calls to alias below produce different outputs, because the object associated with the variable my_own_id changes between the two calls:
>>> def my_own_id():
... me = my_own_id
... return id(me)
...
>>> alias = my_own_id
>>> alias()
4301701560
>>> my_own_id = None
>>> alias()
4296513024
What can I assign to me in the definition of my_own_id so that its output remains invariant wrt subsequent re-definitions of the my_own_id variable? (IOW, so that the internal me variable always refers to the same function object?)
(I can get the current frame (with inspect.currentframe()), but it contains only a reference to the current code object, not to the current function.)
P.S. The motivation for this question is only to know Python better.
It seems that referring to my_own_id will look for 'my_own_id' in the global namespace dictionary, so it will always be the name used on function definition. Since that name can be assigned to different values, the value retrieved can also change. If you make me a default argument, you can assign it to the function itself at function definition to keep a reference to the actual function.
You could use this decorator which implicitly passes the original function itself as the first argument.
>>> from functools import wraps
>>> def save_id(func):
#wraps(func)
def wrapper(*args, **kwargs):
return func(func, *args, **kwargs)
return wrapper
>>> #save_id
def my_own_id(me): # me is passed implicitly by save_id
return id(me)
>>> alias = my_own_id
>>> alias()
40775152
>>> my_own_id = 'foo'
>>> alias()
40775152
Indeed, if you rely only on the function name, if that name is overitten in the global variable space (in the module the function was defined), a reference using the name of the function itslef will fail
The easier, more maintanable way is to write a decorator for that, that would provide a nonlocalvariable containing a reference to the function itself.
from functools import wraps
def know_thyself(func):
#wraps(func):
def new_func(*args, **kwargs):
my_own_id = func
return func(*args, **kwargs)
return new_func
And can be used as:
>>> #know_thyself
... def my_own_id():
... me = my_own_id
... return id(me)
...
There is another possible approach, far from being this clean, using frame introspection
and rebuilding a new function re-using the same object code. I had used this on this post
about a self-referential lambda expression in Python:
http://metapython.blogspot.com.br/2010/11/recursive-lambda-functions.html
Well, if you don't mind calling a function (to get the desired function into the global scope), you can wrap the function to protect its definition:
>>> def be_known():
... global my_own_id
... def _my_own_id():
... return id(_my_own_id)
... my_own_id = _my_own_id
...
>>> be_known()
>>> my_own_id()
140685505972568
>>> alias, my_own_id = my_own_id, None
>>> alias()
140685505972568
Note that the protected function must call itself with the nonlocal name, not the global name.
The decorator approach is probably the best one. Here are some more for fun:
Hijack one of the function arguments to provide a static variable.
def fn(fnid=None):
print "My id:", fnid
fn.func_defaults = (id(fn),)
There are a few ways to get the current function here: Python code to get current function into a variable?; most of these involve searching for currentframe.f_code in a variety of places. These work without any modification to the original function.
import inspect
def _this_fn():
try:
frame = inspect.currentframe().f_back
code = frame.f_code
return frame.f_globals[code.co_name]
finally:
del code
del frame
def myfunc(*parms):
print _this_fn()
>>> myfunc(1)
<function myfunc at 0x036265F0>
>>> myfunc
<function myfunc at 0x036265F0>
It's due to scope
>>> def foo():
... x = foo
... print x
...
>>> foo()
<function foo at 0x10836e938>
>>> alias = foo
>>> alias()
<function foo at 0x10836e938>
>>> foo = None
>>> alias()
None
>>> foo = []
>>> alias()
[]
>>> del foo
>>> alias()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in foo
NameError: global name 'foo' is not defined
>>>
Luke had an idea but didn't appear to develop it: use a mutable default parameter to hold the value in the function object. Default parameter values are evaluated only once, when the function is defined, and retain their previous value after that.
>>> def my_own_id(me=[None]):
if not me[0]:
me[0] = my_own_id
return id(me[0])
>>> alias = my_own_id
>>> alias()
40330928
>>> my_own_id = None
>>> alias()
40330928
This requires care on your part to never call the function with a parameter.
Just for the sake of curiosity I wanna know this..
I know scope of inner function is limited to outer function body only, but still is there any way so that we can access the inner function variable outside its scope or call the inner function outside its scope ?
In [7]: def main():
...: def sub():
...: a=5
...: print a
...:
In [8]: main()
In [9]: main.sub()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/home/dubizzle/webapps/django/dubizzle/<ipython-input-9-3920726955bd> in <module>()
----> 1 main.sub()
AttributeError: 'function' object has no attribute 'sub'
In [10]:
>>> def main():
... def sub():
... a=5
... print a
...
>>> main.__code__.co_consts
(None, <code object sub at 0x2111ad0, file "<stdin>", line 2>)
>>> exec main.__code__.co_consts[1]
5
You can if you return the inner function as a value
>>> def main():
... def sub():
... a = 5
... print a
... return sub
...
>>> inner = main()
>>> inner()
5
or you can attach it to main as a property (functions are objects after all):
>>> def main():
... def sub():
... a = 5
... print a
... main.mysub = sub
...
>>> main()
>>> main.mysub()
5
but you better document your very good reason for doing this, since it will almost certainly surprise anyone reading your code :-)
No, you can't. The inner function is not an attribute of the outer function.
The inner function only exists after its def statement is executed (while the outer function is executed), and it stops to exist when the function exits.
You could return the inner function, of course.
A function is just another object in Python and can be introspected.
You can get the outer function body at runtime and parse/eval it to make the function available in the current namespace.
>>> import inspect
>>> def outer():
def inner():
print "hello!"
>>> inspect.getsourcelines(outer)
([u'def outer():\n', u' def inner():\n', u' print "hello!"\n'], 1)
Not really the same thing as calling outer.inner(), but if you are not making the inner function explicitly available outside the scope of the outer function, I guess it is the the only possibility.
For example, a very naive eval attempt could be:
>>> exec('\n'.join([ line[4:] for line in inspect.getsourcelines(outer)[0][1:] ]))
>>> inner()
hello!
An inner function is just a local variable like any other so the same rules apply. If you want to access it you have to return it.
Can you please explain why 'hello world' isn't returned below? What do I need to modify for it to be expressed properly when called? Thanks.
>>> class MyClass:
... i=12345
... def f(self):
... return 'hello world'
...
>>> x=MyClass()
>>> x.i
12345
>>> x.f
<bound method MyClass.f of <__main__.MyClass instance at 0x060100F8>>
f is a method, so you need to call it. i.e. x.f()
It's no different than if you define a function without the class:
def f():
return 'something'
If you just refer to f, you'll get the function itself
print f
yields <function f at 0xdcc2a8>, while
print f()
yields "something".
When inside the REPL (or the Python console, or whatever) the value returned by the last statement will always be printed. If it is just a value the value will be printed:
>>> 1
1
If it is an assignment, then nothing will be printed:
>>> a = 1
But, watch this:
>>> a = 1
>>> a
1
Ok, so in your code above:
>>> x=MyClass()
>>> x # I'm adding this :-). The number below may be different, it refers to a
# position in memory which is occupied by the variable x
<__main__.MyClass instance at 0x060100F8>
So, the value of x is an instance of MyClass located at a spot in memory.
>>> x.i
12345
The value of x.i is 12345, so it will be printed as above.
>>> x.f
<bound method MyClass.f of <__main__.MyClass instance at 0x060100F8>>
The value of f is a method of x (that's what it means to have def in front of something, it is a method). Now, since it is a method, let's call it by adding the () after it:
>>> x.f()
'hello world'
The value returned by f method on the MyClass instance in the variable x is 'hello world'! But wait! There are quotes. Let's get rid of them by using the print function:
>>> print(x.f()) # this may be print x.f() (note the number of parens)
# based on different versions of Python.
hello world