Python dir() function with variable arguments - python

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

Related

Using Python's inspect library to check if a dynamically named function exists

I'm running a python program (Python 2.7.5) that calls functions dynamically using the eval method. I need to find out if the function exists -before- I do any of the prerequisite calculations needed to run it if it does exist.
To do this, I've been trying to employ the inspect python library, which uses inspect.isfunction(foo). However it cannot take in dynamically named functions as a string to determine if the function exists.
import inspect
for i in range(1, 4):
if inspect.isfunction("hello" + i):
print("Function does exist")
else:
print("Does not exist")
def hello1():
print("Hello")
def hello3():
print("Hello2")
At the moment it is not returning the correct boolean value as to whether or not the function exists. Is there any way of converting "hello" + 1 to the function itself (hello1 instead of "hello1")
You can use a try block :
try:
hello1
except NameError:
print("The function does not exist")
else:
print("The function exist")
You need to first get, if possible, the object bound to the name in the current scope.
if inspect.isfunction(globals().get('hello{}'.format(i))):
If hello1 is defined, the call to get will return the object bound to that name, and isfunction can determine if it is, indeed, a function.
If it is not defined, get returns None, for which isfunction will return False.

Can I name a variable "now" in python

This may seem a naive question but I did not find any answer so far in the web and I do not want to cause any inconsistent behavior in my code.
Can I name a variable now in my python code? there is a function named now() that's why I have doubts.
Example:
now = datetime.datetime.now()
Can this be treated as any ordinary variable that stores the returned value by datetime.datetime.now() ? or can it behave differently at any point?
Below are the keywords that are used in python, Apart from that you can use any keyword you want
False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
I hope that answer your question
now is not a keyword in python, so you can use it as a variable name.
Is there any chance of interfering with datetime.datetime.now()? No.
To elaborate: there is no function named now() either; it is tied to the datetime object (it's a class method), and you'll always need datetime.now() to use it. So it's always distinguished from your variable named now.
Only if you assign it as follows:
now = datetime.datetime.now
Here, the new variable named now equals the datetime.now() function (not the result of the function). But in this case, you're completely responsible yourself for this assignment. Even then, changing now to something else will not change datetime.now.
Using, however
now = datetime.datetime.now()
assigns the results of the function call to the variable now (not the function itself), and the function remains as is.
What is worth paying attention to, is whether you should overwrite built-in functions. This is the list of built-in functions in Python 3.7.
You can assign a value to each of these names, but then you effectively lose that function*, and you may get in trouble later on. For example:
str = "Hello there"
a = 123
<more code>
value = str(a) # causes a TypeError, because we re-assigned str
So try to avoid that (list = [1,2,3] is another common mistake that should be avoided).
But now() is not a built-in function, as explained above.
* there are ways to retrieve the original built-in function, even after reassignment, but that's outside the scope of this topic.
import this says
Namespaces are one honking great idea -- let's do more of those!
You can use now as a variable even though there is a function called datetime.datetime.now() because that lives in a different namespace. Every module (like module datetime) is a namespace, and every class or type inside that module (like datetime.datetime) is a separate namespace. Even inside a function you can create a local variable that has the same name as one defined in the surrounding code:
a = 1
def f(x):
a = x + 2
print (a)
f(4) # prints 6
print (a) # prints 1
though doing that may confuse readers of your code, including yourself.
It will work as Varibale
from datetime import datetime
now = datetime.now()
now
output:
datetime.datetime(2018, 8, 3, 16, 36, 54, 182551)
type of "Now" variable is
type(now)
datatype of Variable is
datetime.datetime
from this we can say now will work as Simple Variable

Return variable from a function

This section of a program I am writing is supposed to take the random choice and then print it outside the function (I can't print from within as I need the variable later).
I am sure there is a simple solution to this, but I am unsure what it is.
#python2
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
Choice = random.choice(RandTurn)
return(Choice)
print Choice
Thank you.
Add the line
Choice = CompTurn()
before your print statement. Because the variables you declare within the function are not known outside of it, you have to store (or print directly, but then you cannot store it) the returned variable in a new variable.
You have defined your function correctly, but you never executed it! (You'll see that if you make it print something as a diagnostic.) You must run it to get the result:
chosen = CompTurn()
print chosen
Note that I used a different variable name. You could use the same variable name as a variable in your function, but it's still a different variable than the one in your function.
It is also important to realize that your function returns a value, not a variable. You can assign the value to a variable (as above) or print it immediately.
print CompTurn()
About your program, you don't need the brackets for return. It's s statement, not a function.
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
Choice = random.choice(RandTurn)
return Choice
Shorter:
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
return random.choice(RandTurn)
To print the return value, You can save it in a variable and print it
ret = CompTurn()
print ret
Or print directly:
print CompTurn()

Python issue when returning function from another file

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.

Python: Substitute variable values before passing to another function

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

Categories