program is running fine but cannot being import with IndexError - python

I'm using python 2.7, the following is the simplified version of my script:
executor.py
import sys
def someCal(num):
num = int(num)
print num*num
someCal(sys.argv[1])
so python executor.py 13 would print out 169, it's working as expected.
and I have another script, I want to make use of someCal() function in executor.py so I import it
main.py
import executor
to_count = 999
executor.someCal(to_count)
I got the error message below when execute python main.py:
File "main.py", line 3, in <module>
import executor
File "/Users/mac/executor.py", line 13, in <module>
someCal(sys.argv[1])
I don't know why it keep mentioning about line 13 in executor.py, because I didn't use that part.
Thanks in advance!

from executor import *
It is a better method and will work fine as you wanted.No need if name == 'main': with this method. Also you can call your functions with their names.Like:
from executor import *
print (someCal(10))
Edit for example:
executor.py
def someCal(num):
num = int(num)
return num*num
another.py
from executor import *
print (someCal(10))
Output:
>>>
100
>>>
If you working with functions, you should return a value in function, not print. If you return a value, you can print it later.But if you dont use return and just keep it like print num*num, then you cant use it later with print function. You can try and see that.So, returning a value is important in functions.
For your second question, check this one: What does if __name__ == "__main__": do?
Python is the best language about clear codes, so you should keep it clear, sys is not necessary for you. And you dont need if name == 'main': this statement, remember every .py file is a module, so if you can import any module without that statement,like import random; then you can import your own modules too.Just care about they have to stay in same directory so Python can find your own module/file. Keep it simple :-)
Another import method for a module is:
import executor as ChuckNorris
print (ChuckNorris.someCal(10))
Output is same of course, you can write whatever you want instead of ChuckNorris, but be sure that name doesnt overlap with another function name in your program. For example you have a .py file called Number.py, you will import this file to another file, but you cant be sure is there any function called Number in another one, so you can call it like import Number as whatyouwanttocallit and you will avoid from that problems.

When you import executor in main.py, it actually doing python executor.py, I suggest you change your executor.py to:
if __name__ == '__main__':
someCal(sys.argv[1])
and, you might want to add defensive code like if len(sys.argv)>1 before use sys.argv[1] directly

Related

Running python program with arguments from another program

I want to call a python program from current program,
def multiply(a):
return a*5
mul = sys.argv[1]
I saved this file as test.py.so from the current file I'm calling it but i want to run the code in parallel like multiprocessing queue,But its not working.
what I tried so far,
import os
import sys
import numpy as np
cwd = os.getcwd()
l = [20,5,12,24]
for i in np.arange(len(l)):
os.system('python test.py multiply[i]')
I want to run the main script for all list items parallelly like multiprocessing. How to achieve that?
If you want to make your program work like that using that the os.system, you need to change the test.py file a bit:
import sys
def multiply(a):
return a*5
n = int(sys.argv[1])
print(multiply(n))
This code written like this takes the second element (the first one is just the name of the file) of argv that it took when you executed it with os.system and converted it to an integer, then executed your function (multiply by 5).
In these cases though, it's way better to just import this file as a module in your project.

Issue with import in python

So, I'm quite new to python, and I tried to import a function that I had written in one of my files into another file that I was working on.
Here is the code in the file that I'm trying to import the function from:
def print_me(x):
return 2 * x
print(print_me(5))
Here is the code in my other file:
from question2 import print_me
print(print_me(5))
Now when I run my second file, the answer (10) gets printed twice.
I want to know the reason why my print function in my first file (from which I imported my function) also gets executed.
When import a module, in fact you're importing the whole codes from that file, including print statements and others.
In order to reach this, you should either remove print statement in the first file where you define print_me function, or add this code to your file:
if __name__ == "__main__":
# your code goes here
Have Fun :)
When you import a file, every statement in this file is executed. Therefore both the def statement and the print function call are executed, printing "10" once. Then the code from your other file is executed, printing "10" a second time.
The proper way to deal with this issue is to put all the code that shouldn't be executed on import inside this block:
if __name__ == "__main__":
# code that should not be executed on import
This ensures that the code from the first file is only executed when run.

NameError when importing a dict

I've got a script where I want to import a dict from a file and then use it to execute functions.
The file codes.py is as follows:
rf_433mhz = {
"0x471d5c" : sensor_LaundryDoor,
}
And the file it's using is as follows:
#!/usr/bin/python
import mosquitto
import json
import time
def sensor_LaundryDoor():
print "Laundry Door Opened"
mqttc.publish("actuators", json.dumps(["switch_HallLight", "on"]))
from codes import rf_433mhz
but I'm getting a NameError.
Traceback (most recent call last):
File "sensors.py", line 11, in <module>
from codes import rf_433mhz
File "/root/ha/modules/processing/codes.py", line 2, in <module>
"0x471d5c" : sensor_LaundryDoor,
NameError: name 'sensor_LaundryDoor' is not defined
Is there any way to do what I'm trying to do? It seems to be getting stuck on not having the function inside codes.py
I'm trying to call sensor_LaundryDoor() as follows
def on_message(msg):
inbound = json.loads(msg.payload)
medium = inbound[0]
content = inbound[1]
if str(medium) == "433mhz":
try:
rf_433mhz[str(content)]()
except:
print "Sorry code " + content + " is not setup"
import isn't include. It won't dump the source code of codes.py into your script; rather, it runs codes.py in its own namespace, almost like a separate script, and then assigns either the module object or specific module contents to names in the namespace the import is in. In the namespace of codes.py, there is no sensor_LaundryDoor variable.
The way you're dividing the code into modules isn't very useful. To understand codes.py, you need to understand the other file to know what sensor_LaundryDoor is. To understand the other file, you need to understand codes.py to know what you're importing. This circular dependency would negate most of the benefit of modularizing your code even if it wasn't an error. Reorganize your code to fix the circular dependency, and you'll probably fix the NameError as well.
The problem is that in your dictionary that you're importing, you're setting the value of 0x471d5c to a variable that was either not defined, or not defined in that scope.
An example of this would be like:
Codes.py
#!/usr/bin/python
sensor_LaundryDoor = 'foo'
rf_433mhz = {
"0x471d5c" : sensor_LaundryDoor,
}
Main files
#!/usr/bin/python
from test import rf_433mhz
print rf_433mhz["0x471d5c"]
There are hacky ways to solve this but it looks like the real issue is that you're trying to write C-style code in Python. The Python way to do things would be to import sensor_LaundryDoor in codes.py before using it, and if this introduces a circular reference then that's a design issue.
Maybe you need three modules, events.py with your main loop which imports the dict from codes.py which imports the functions from sensors.py.

how to run python script from shell

I have a noob question.
I got a python script path1/path2/file.py
The script has a function:
def run (datetime = None):
In the shell I call
import path1.path2.file
import datetime
path1.path2.file.run(datetime = datetime(2011,12,1))
but I am getting
TypeError: 'module' object is not callable
whats the correct way to call the method in the shell?
The problem is actually in the datetime module.
You are trying to call the module itself.
The function you want to call is itself called datetime.
so what you want to call is:
datetime.datetime()
OR you can import the function with:
from datetime import datetime
and then call it with:
datetime()
You can write:
import path1
path1.path2.file.run(...)
Or:
from path1.path2.file import run
run(...)
Don't forget that you need an __init__.py file in each directory (path1 and path2) to make the directory as a module (and then, allow it to be importable.). That file can just be empty if you have nothing to put in it.
Try the following:
from path1.path2.file import run
If none of these work, here is a (a little bit dirty) way of doing it:
# Python <= 2.7
namespace = {}
exec open("path1/path2/file.py").read() in namespace
namespace["run"](datetime=datetime.datetime(2011,12,1))
or
# Python >= 3.0
namespace = {}
exec(open("path1/path2/file.py").read(), namespace)
namespace["run"](datetime=datetime.datetime(2011,12,1))
Of course you could omit the namespace = {} and the in namespace / , namespace parts, but then, the code in file.py might actually change other variables in your shell.
you can import a folder doing
import path1
and then call simply the script doing:
path1.path2.file.run(...)
otherwhise if you do not want to include all the other stuff within the directory you can try with
from path1.path2.file import run
in this case you have only to call:
run()
Cheers,

python interactive mode module import issue

I believe I have what would be called a scope issue, perhaps name space. Not too sure I'm new to python.
I'm trying to make a module that will search through a list using regular expressions. I'm sure there is a better way of doing it but this error that I'm getting is bugging me and I want to understand why.
here's my code:
class relist(list):
def __init__(self, l):
list.__init__(self, l)
def __getitem__(self, rexp):
r = re.compile(rexp)
res = filter(r.match, self)
return res
if __name__ == '__main__':
import re
listl = [x+y for x in 'test string' for y in 'another string for testing']
print(listl)
test = relist(listl)
print('----------------------------------')
print(test['[s.]'])
When I run this code through the command line it works the way I expect it to; however when I run it through python interactive mode I get the error
>>> test['[s.]']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "relist.py", line 8, in __getitem__
r = re.compile(rexp)
NameError: global name 're' is not defined
While in the interactive mode I do import re and I am able to use the re functions, but for some reason when I'm trying to execute the module it doesn't work.
Do I need to import re into the scope of the class? I wouldn't think so because doesn't python search through other scopes if it's not found in the current one?
I appreciate your help, and if there is a better way of doing this search I would be interested in knowing. Thanks
Move the "import re" out of the bottom "if..." to the top of the file:
import re
class ....
You're only importing the re module when run as a program, not imported as a module.
(Also, Python style prefers upper-case class names.)
Python does not run anything "ahead of time"; it runs code when it encounters it. The only thing that's done "ahead of time" is to translate the source code into bytecode.
When you import the module, __name__ is the name of the module, rather than __main__. Thus, the code in the if block at the end is not executed, and re is not imported. When you then attempt to use the class, the name re is looked up right then, when it's needed (to access re.compile), and not found (because the module wasn't imported earlier).

Categories