I want to determine whether the input string is a valid function name or not.
Is there any way to substitute the value of the variable before being passed to isfunction call ?
#!/usr/bin/python
def testFunc():
print "Hello world!";
return;
myString = "testFunc";
isfunction(testFunc); // This returns **True**
isfunction(myString); // This returns **False**
One way of doing that is using eval, which interprets string as code:
try:
eval(myString)
except NameError:
# not a function
Assuming you want to check to see if there exists a loaded function with You could try this:
try:
if hasattr(myString, '__call__'):
func = myString
elif myString in dir(__builtins__):
func = eval(myString)
else:
func = globals()[myString]
except KeyError:
#this is the fail condition
# you can use func()
The first if is actually unnecessary if you will always guarantee that myString is actually a string and not a function object, I just added it to be safe.
In any case, if you actually plan on executing these functions, I'd tread carefully. Executing arbitrary functions can be risky business.
EDIT:
I added another line to be a bit more sure we don't actually execute code unless we want to. Also changed it so that it is a bit neater
Related
I have a concept where I store values returned by functions in variables which makes it easier for me.
But I am having the problem that the value in the variable isn't dynamically calling the function each time. So it returns the same value all the time.
I have made a code snip to illustrate it in a easy way:
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
test = value()
while True:
print test
time.sleep(10)
Output:
0.00649
0.00649
In this case, in the while true when I print test, it returns the same value, even though I am calling the function value(). How can I solve this issue? I know I can put the function in the while loop, but I want to have it as a variable.
The previous answers are correct, but please let me elaborate.
In the world of Python, things have very precise meanings but it's not always clear what is what if you are just getting started.
Expressions are things that have a value, and they include things like 123, some_variable and 10 / 2. The name some_variable is called an identifier, simply because it identifies a value. Just like the name Scruffy might identify your dog.
Statements are things that affect the program flow or the state of your program, but lack a value. The following are examples of statements:
if x > 10:
x -= 1
And
def foo(x):
print("The value of x is", x)
Unlike in JavaScript, for example, where almost everything is an expression (and has a value), you can not do this:
my_function = def foo(x): print("The value of x is", x)
The previous def statement will create a function by the name foo, but the statement itself doesn't have a value. The name foo will refer to a value, however. It means that when you write foo, the value will be a thing, and this thing is a function!
The expression x() on the other hand will do two things. First it will look up the value of the identifier x. Hopefully this value is a function. After that, the parentheses means that the value will be called. What happens if x is not a function, then?
>>> x = 10
>>> x()
Traceback (most recent call last):
File "<ipython-input-3-7354d77c61ac>", line 1, in <module>
x()
TypeError: 'int' object is not callable
Big Fat Error: 10 is not a "callable". Callable means something that can be called like a function.
The parentheses are, as you probably know, a list of arguments. In this case the list is simply empty so when you write x() you are saying "call whatever the name 'x' is referring to but don't send any arguments".
A function call always has a value, since it's an expression. If you don't explicitly return anything, the value will simply be None.
To answer your question, finally, let's play the substitution game. The rules are simple, any expression can be replaced by its value:
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
This is a statement, so it doesn't have a value. A function is created with the name value, however.
The function consists of two statements (no value, again), a variable assignment and a return statement.
The thing to the right of the = is an expression however. Short story:
requests is referring to the requests module
get is referring to a module-global function in the above module
get('...') is calling this function, and something is returned.
The "something" has a property called elapsed, which has a property called total_seconds.
total_seconds is an identifier that refers to a callable. The callable is called without any arguments (total_seconds()) and something is returned. Probably a number, based on the name. Let's say its value is always 10, for simplicity.
The next statement is another assignment:
test = value()
This can be thought of as "let the name 'test' refer to the value that is returned by the callable identified by the name 'value' when it is called with an empty argument list". In our case, the function object called value will be called, resp will be assigned the value 10, then the return statement will let the caller know that this call is sending the value 10 back. The name test will refer to the value 10, from now on.
Let's go over the loop, quickly:
while True:
print test
time.sleep(10)
Do the following until the end of Time:
print (a statement in Python 2, an expression in Python 3!) has the side-effect of printing stuff to the screen. Otherwise it doesn't do much.
The stuff, in this case, is whatever the value of the expression test is. We already know that the identifier test is referring to the value 10. It will simply print "10" to the screen.
Sleep for ten seconds.
Repeat.
You probably want to invoke some function at each iteration of the loop ("invoke" is basically latin for "call", I like fancy words). Otherwise the program will just print "10", "10", "10", over and over again. To fix this this, you first have to change the expression evaluated as part of the print statement from just an identifier (test) to a function call:
print test()
But this will, as we saw before, raise a Big Fat Error since 10 is not a callable function. To fix it (that's what programmers do, right?) you also need to change the value of test from 10, since it's not a callable, to the function. A function can be referred to simply by its name, so just change this line:
test = value() # equals ten
To this:
test = value # equals the function called "value"
The function now has two names, the old name "value", and the new name "test". Each step in the loop will request the page again and return the new time it took for the request to complete. If the request times out you will have a different kind of crash, but that's another story.
Further information can be found in the Python Language Reference.
test = value() isn't storing the function it's storing the results. You should just call value() in your loop or if you want to assign the function it would be test = value and then test() in your loop.
test = value() calls the function and stores the return value. It does not store the function. test = value would store the function, but the you need to print test() in order to call it.
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
test = value
while True:
print test()
time.sleep(10)
You can change your code like this..
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
test = value()
while True:
print test
time.sleep(10)
change this line
test = value
to
test = value()
Now means you are storing your function in a variable.
I'm having a bit of an issue when trying to return a function from another file.
main.py:
from master_input import load_input
class Vera(object):
def __init__(self):
masterinput = load_input()
self.masterinput = masterinput
def load_masterinput(self):
return self.masterinput
master_input.py:
import sys
def load_input():
if sys.version_info <= (3,0,0):
masterinput = raw_input()
elif sys.version_info >= (2,7,11):
masterinput = input()
return masterinput
There seems to be no output when running the first file. I want it to return masterinput in the second file because if I were to end the function with load_input(), in the second file, it would just output without even returning self.masterinput in the first file.
You don't show an example of instantiated one of the Vera() options nor to you show any methods that would be using (displaying/printing or otherwise manipulating) this masterinput attribute of your Veta() instance.
So it seems quite likely that your code doesn't seem to be "doing" anything. You'd declared what the objects look like, how to instantiate them and how to respond to a (poorly named) load_masterinput() method call.
Also your module isn't returning a function. When an object is instantiated it, that could will be returning a string, the result of calling either the input() or raw_input() built-in function.
By the way, the smart way, in my opinion, to handle the change from Python2.x raw_input() to Python3 input() is to use code like this:
#!python
if 'raw_input' in dir(__builtins__):
input = raw_input
Note that I'm assigning the function raw_input to the name input ... I'm NOT calling the function and assigning the results of its evaluation here.
Then all my code can use input() and we can forget that the Python2 (evaluated) input() semantics ever existed.
If I want to actually return a function from a function here's one way to do so:
#!python
# filename: my_input.py
def get_input_function():
if 'raw_input' in dir(__builtins__):
# Python2.x and earlier
return raw_input
else:
# Python3
return input
... I would then call this something like so:
#!python
import my_input
input = my_input.get_input_function()
This is unnecessarily obtuse. There's no reason to do something like this for something so trivial. There are cases where you might imagine calling some function, with certain arguments and returning different functions based on those arguments. However, in most cases, you'd still be better off creating a class and instantiating an instance of that.
The problem is that you aren't actually returning the functions, but are instead calling the functions and returning the result. Just remove the parentheses to change the function calls into the functions themselves. I.e., change:
return func()
to:
return func
The return value will then be a callable function.
For fun/to practice python, I am trying to create a program that displays the contents of a module. Looks like this:
import sys
print "Here are all the functions in the sys module: "
print dir(sys)
function = raw_input("Pick a function to see: ")
cnt = True
while cnt:
if function in dir(sys):
print "You chose:", function
cnt = False
else:
print "Invalid choice, please select again."
cnt = True
print dir("sys." + function)
But every time, no matter what string the variable function is set to, the dir("sys." + function) call always defaults to the same output as dir(string) (or so I think!)
What is happening and is there a way for me to do this properly and get the output I really want (for example, the variable function is set to stdin and I get the output for dir(sys.stdin))?
You want to retrieve the actual object from the module; use the getattr() function for that:
print dir(getattr(sys, function))
dir() does not interpret the contents of the objects you pass to it; a string that happens to contain a value that corresponds to the name of a function in a module is not dereferenced for you.
f = getattr(sys, function) # get function object
help(f) # display help for the function
Note: dir(f) would return the same info for all functions with the same type.
As dir works on objects, you need to get the object somehow from the name.
First option is to use getattr:
print dir(getattr(sys, function))
If you want to be more flexible (and are ready to take security risk), you can use eval:
print dir(eval('sys.' + function))
So basically, let's say you define a function and then write something in () brackets after then function. If I write function(gay), it ends up as 'error name not defined' Python2.73
def lenRecur(aStr):
'''
aStr: a string
returns: int, the length of aStr
'''
print type(aStr)
return
def lenRecur2(aStr):
'''
aStr: a string
returns: int, the length of aStr
'''
s = str(aStr)
print type(s)
return
So when I type lenRecur(gay) or lenRecur2(gay), it ends up as an error whatever I do. So is there a way to avoid it? Without using "" quote marks.
No - unless your input is already a variable that holds a string (or another object).
However, you could use a try-except block (but it won't actually do anything if there's an error).
try:
lenRecur(foo)
lenRecur2(foo)
except NameError:
pass
The error occurs before the function even gets called. Python tries to evaluate the arguments before calling the function. So, Python encounters the bare name gay and wonders, "What the hell is that?"
When it fails to find its value in the local, enclosing, global or builtin scopes, it raises a NameError.
There is no way around this. You must clearly specify what you mean. If gay is a string, you must use quotes.
I have a function defined which includes a return statement but no value is handed back. My code is as follows:
def seed(addy):
# urllib2 stuff is here
seed_result = re.search('<td>Results 1 - \d+ of (\d+)',seed_query) # searches for '<td>Results 1 - x of y', captures 'y'
seed_result = seed_result.group(1) # this is 'y' from above
# there's a call to a different function here which works properly
# other stuff going on here pertaining to addy but seed_result still has my string
# now I want to return the seed_result string...
return seed_result
# ... some code outside of the seed function, then I call seed...
seed(addy)
print "Result is %s" % seed_result
I have tried this with and without defining seed_result outside of the function to "initialize" it but this has no impact on the outcome which is that my print statement at the end yields "Result is " - there's no seed_result. I have also wrapped seed_result in parenthesis in the return statement though I believe how I have it is correct. The parens didn't make a difference.
A set up a very basic, yet similar, function in the Python shell and called it as I do here but that works. Not sure what I'm missing.
Thanks for the feedback and guidance.
You're not using the return value (e.g. assigning it to a variable). Try this:
result = seed(addy)
print "Result is %s" % result
Two ways of solving this:
First, the proper, obvious, and easy way is actually using the returned value:
seedresult = seed(addy)
Or you use a global variable (bad style - avoid at any cost):
seedresult = None
def seed(addy):
global seedresult
...
This is caused by None being assigned to seed_result during the execution of your function.
As Jon Skeet identified, you are doing nothing with the return value of your function. You should also address the issues below, though.
In particular, you are doing nothing with the parameter addy, and searching a global variable seed_query. I imagine the behaviour you are seeing is a result of that.