Correctly calling variables inside a function - python

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
>>>

Related

unable to use attribute from a python function in another python script

I want to use one of the attributes returned by a function in a python script (x) into a python script (y)
The communication between both scripts works well; I can get functions and attributes, but doesn't allow me to attributes returned by a function.
Here is how I worked:
x.py
def func():
b = 10
a = 15
return [a,b]
c = 20
y.py
from x import func
import x
print (x.c)
print (func.b)
I get the "c" value and the following error AttributeError: 'function' object has no attribute 'b'
I have tried also to print x.b, and I've got AttributeError: module 'WorkingLSTM' has no attribute 'b'
Thanks in advance
The way to call func is by using func(), which would give you [a,b].
example:
funcResult = func()
a = funcResult[0]
b = funcResult[1]
funcResults is the return value from func(), that is the list [a,b].
That's not allowed, you have to call the function to get the value from the functions returned list.
a, b = func()
print(b)
# or just...
print(func()[1])
PS: It's "not allowed" because it doesn't make sense in any way; when there is no function call, there is not variable b at all. You might take a look at classes, they can hold static variables.
you cannot access local variables of a function.
these variables exist only during the the time where func is executed and are destroyed afterwards.
You can of course call the function and look at the result, but the result is just a list with two values
rslt = func()
print("A = ", rslt[0])
print("B = ", rslt[1])
The variable was declared inside a function making it a local variable and as such it can"t be accessed outside the function.
The variable is declared outside of the function making it a global variable and is not in anyway tied to your function.
The concept of attributes relates to Classes and you are dealing with a function so you might have to treat it as a class object.
If you are concerned bout accessing the local variables, you might as well do this:
y.py
from x import *
d = func() # func returns a list which is now
# identified/referenced by variable d
# displays the elements in the list using index position
print(d[0])
print(d[1])
If you want to use attributes, you may create a callable class instead of function:
class Func:
def __init__(self):
self.b = 10
self.a = 15
def __call__():
return [self.a, self.b]
func = Func()
Python has the concept of the scope. Local variables have no effect outside the function.
If you want to use it, use class and self or make getter function(but it's not Pythonic).
x.py
class X:
def __init__(self):
self.b = 10
self.a = 15
self.c = 20
def func(self):
return [self.a, self.b]
y.py
from x import X
x = X()
print(x.c)
print(x.func()[1])

How to access a Python function using it's __name__?

I have a function func :
def func(a):
print a
func.__name_ = "My_Function"
To get the name of the function I will just do func.__name__.
But is there a way to call func() by using its name i.e. "My_Function"?
Edit: There are going to be large number of functions for which this has to be done. Is there any better solution apart from keeping a mapping of function.name to the function. ?
It will be much easier to use a dictionary:
def func():
print('func')
func_dict = {"My_Function": func}
func_dict["My_Function"]()
# 'func'
Assuming that you want to access functions that are defined in global scope (not part of any class/object):
def foo():
print "foo"
def bar():
print "bar"
foo.__name__ = "1"
bar.__name__ = "2"
# locals().items() will return the current local symbol table, which is an iterable and
# it contains the globally defined functions.
symbol_table = locals().items()
# we will generate a list of functions that their __name__ == "1"
one_functions = [value for key, value in symbol_table if callable(value) and value.__name__ == "1"]
# now we can call the first item on the list - foo()
one_functions[0]()

What is the specific name of this output?

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')|

How to get function object inside a function (Python)

I want to have something like
def x():
print get_def_name()
but not necessarily know the name of x.
Ideally it would return 'x' where x would be the name of the function.
You can do this by using Python's built-in inspect library.
You can read more of its documentation if you want to handle more complicated cases, but this snippet will work for you:
from inspect import getframeinfo, currentframe
def test_func_name():
return getframeinfo(currentframe()).function
print(test_func_name())
Functions in Python are objects, and as it happens those objects do have an attribute containing the name they were defined with:
>>> def x():
... pass
...
>>> print x.__name__
x
So, a naïve approach might be this:
>>> def x():
... print x.__name__
...
>>> x()
x
That seems to work. However, since you had to know the name of x inside the function in order to do that, you haven't really gained anything; you might have well just have done this:
def x():
print "x"
In fact, though, it's worse than that, because the __name__ attribute only refers to the name the function was defined with. If it gets bound to another name, it won't behave as you expect:
>>> y = x
>>> y()
x
Even worse, if the original name is no longer around, it won't work at all:
>>> del x
>>> y()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in x
NameError: global name 'x' is not defined
This second problem is one you can actually get around, although it's not pretty. The trick is to write a decorator that can pass the function's name into it as an argument:
>>> from functools import wraps
>>> def introspective(func):
... __name__ = func.__name__
... #wraps(func)
... def wrapper(*args, **kwargs):
... return func(__name__=__name__, *args, **kwargs)
... return wrapper
...
>>> #introspective
... def x(__name__):
... print __name__
...
>>> x()
x
>>> y = x
>>> y()
x
>>> del x
>>> y()
x
... although as you can see, you're still only getting back the name the function was defined with, not the one it happens to be bound to right now.
In practice, the short (and correct) answer is "don't do that". It's a fundamental fact of Python that objects don't know what name (or names) they're bound to - if you think your function needs that information, you're doing something wrong.
This sounds like you want to declare an anonymous function and it would return a reference to the new function object.
In Python, you can get a trivial anonymous function object with lambda but for a complex function it must have a name. But any function object is in fact an object and you can pass references around to it, so the name doesn't matter.
# lambda
sqr = lambda n: n**2
assert sqr(2) == 4
assert sqr(3) == 9
# named function
def f(n):
return n**2
sqr = f
assert sqr(2) == 4
assert sqr(3) == 9
Note that this function does have a name, f, but the name doesn't really matter here. We set the name sqr to the function object reference and use that name. We could put the function reference into a list or other data structure if we wanted to.
You could re-use the name of the function:
def f(n):
return n**2
sqr = f
def f(n):
return n**3
cube = f
So, while Python doesn't really support full anonymous functions, you can get the same effect. It's not really a problem that you have to give functions a name.
If you really don't want the function to have a name, you can unbind the name:
def f(n):
return n**2
lst = [f] # save function reference in a list
del(f) # unbind the name
Now the only way to access this function is through the list; the name of the function is gone.
I found a similar solution as Vazirani's, but I did a step forward to get the function object based on the name. Here is my solution:
import inspect
def named_func():
func_name = inspect.stack()[0].function
func_obj = inspect.stack()[1].frame.f_locals[func_name]
print(func_name, func_obj, func_obj.xxx)
named_func.xxx = 15
named_func()
Output is
named_func <function named_func at 0x7f3bc84622f0> 15
Unfortunately I cannot do this with lambda function. I keep trying.

Can we access inner function outside its scope of outer function in python using outer function?

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.

Categories

Resources