NameError when importing a dict - python

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.

Related

Python function from imported file shows as undefined

I have a moveslist.py file with function movesSelection and a main.py file. Within my main.py, I've made sure that my variables are set to global and I had another function makeNewChar. Within makeNewChar, I'm trying to call movesSelection but I get "NameError: name 'movesSelection' is not defined.
Since my moveslist.py uses some global variables from main, I imported main into the file.
For my main.py, I did from moveslist import *. I also tried import movesList and from moveslist import movesSelection. All of those threw back errors.
How can I use movesSelection within my main.py?
There may be a few different reasons but some of the most common are having a file with the same name or likely the file you are looking for is in another directory so i will show you my correct here
[Edit] You should remove the .py when importing example below
## This is "main.py" keep that in mind when viewing
## Change line 4 to import and the python file as Func = Func.py in this context
import Func
Func.Activate()
## This is "Func.py"
class Activate:(
print("Hello World!")
)
Or you may need to do as says below!
##Include file extension and move the file with the folder in the correct space and i'd appreciate it if you'd be so kind to mark this question as correct
import movesSelection.py
Add "from moveslist import movesSelection" into makeNewChar.
You do not have to add the .py suffix when you import.

Python name 'os' is not defined even though it is explicitly imported

I have a module called imtools.py that contains the following function:
import os
def get_imlist(path):
return[os.path.join(path,f) for f in os.listdir(path) if f.endswith('.jpg')]
When I attempt to call the function get_imlist from the console using import imtools and imtools.get_imlist(path), I receive the following error:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\...\PycharmProjects\first\imtools.py", line 5, in get_imlist
NameError: name 'os' is not defined
I'm new at Python and I must be missing something simple here, but cannot figure this out. If I define the function at the console it works fine. The specific history of this module script is as follows: initially it was written without the import os statement, then after seeing the error above the import os statement was added to the script and it was re-saved. The same console session was used to run the script before and after saving.
Based on small hints, I'm going to guess that your code didn't originally have the import os line in it but you corrected this in the source and re-imported the file.
The problem is that Python caches modules. If you import more than once, each time you get back the same module - it isn't re-read. The mistake you had when you did the first import will persist.
To re-import the imtools.py file after editing, you must use reload(imtools).
Same problem is with me I am also trying to follow the book of Programming Computer Vision with Python by Jan Erik Solem" [http://programmingcomputervision.com/]. I tried to explore on internet to see the problem but I did not find any valuable solution but I have solved this problem by my own effort.
First you just need to place the 'imtools.py' into the parent folder of where your Python is installed like C:\Python so place the file into that destination and type the following command:
from PIL import Image
from numpy import *
from imtools import *
Instead of typing the code with imtools.get_imlist() you just to remove the imtools from the code like:
get_imlist()
This may solve your problem as I had found my solution by the same technique I used.

How to run a large amount of python code from a string?

I need to be able to run a large amount of python code from a string. Simply using exec doesn't seem to work, as, while the code runs perfectly in a normal setting, doing it this way seems to throw an error. I also don't think I can just import it as it it hosted on the internet. Here is the code:
import urllib.request
URL = "https://dl.dropboxusercontent.com/u/127476718/instructions.txt"
def main():
instructions = urllib.request.urlopen(URL)
exec(instructions.read().decode())
if __name__ == "__main__":
main()
This is the error I've been getting:
Traceback (most recent call last):
File "C:\Python33\rc.py", line 12, in <module>
main()
File "C:\Python33\rc.py", line 9, in main
exec(instructions.read().decode())
File "<string>", line 144, in <module>
File "<string>", line 120, in main
NameError: global name 'Player' is not defined
The code I'm trying to run is available in the link in the first code snippet.
If you have any questions I'll answer them. Thank you.
Without specifying globals, the exec function (Python/bltinmodule.c) uses PyEval_GetGlobals() and PyEval_GetLocals(). For the execution frame of a function, the latter creates a new f_locals dict, which will be the target for the IMPORT_NAME, STORE_NAME, LOAD_NAME ops in the compiled code.
At the module level in Python the normal state of affairs is globals() == locals(). In that case STORE_NAME is using the module's globals, which is what a function defined within the module will use as its global namespace. However, using separate dicts for globals and locals obviously breaks that assumption.
The solution is to to manually supply globals, which exec will also use as locals:
def main():
instructions = urllib.request.urlopen(URL)
exec(instructions.read().decode(), globals())
You could also use a new dict that has __name__ defined:
def main():
instructions = urllib.request.urlopen(URL)
g = {'__name__': '__main__'}
exec(instructions.read().decode(), g)
I see in the source that the current directory will need a sound file named "pickup.wav", else you'll just get another error.
Of course, the comments about the security problems with using exec like this still apply. I'm only addressing the namespace technicality.
First I thought you might try __import__ with a StringIO object. Might look something like StackOverflow: Local Import Statements in Python.
... but that's not right.
Then I thought of using the imp module but that doesn't seen to work either.
Then I looked at: Alex Martelli's answer to Use of Eval in Python --- and tried to use it on a silly piece of code myself.
I can get the ast object, and the results of the compile() from that (though it also seems that one can simply call compile(some_string_containing_python_source, 'SomeName', 'exec') without going through the ast.parse() intermediary step if you like. From what I gather you'd use ast if you wanted to then traverse the resulting syntax tree, inspecting and possibly modifying nodes, before you compiled it.
At the end it seems that you'll need to exec() the results of your compile() before you have resulting functions, classes or variables defined in your execution namespace.
You can use pipe to put all strings into a child process of python and get output result from it.
Google os.popen or subprocess.Popen

Import statement in library definition does not seem to be executed

I am having a problem that may be quite a basic thing, but as a Python learner I've been struggling with it for hours. The documentation has not provided me with an answer so far.
The problem is that an import statement included in a module does not seem to be executed when I import this module from a python script. What I have is as follows:
I have a file project.py (i.e. python library) that looks like this:
import datetime
class Project:
""" This class is a container for project data """
title = ""
manager = ""
date = datetime.datetime.min
def __init__( self, title="", manager="", date=datetime.datetime.min ):
""" Init function with some defaults """
self.title = title
self.manager = manager
self.date = date
This library is later used in a script (file.py) that imports project, it starts like this:
import project
print datetime.datetime.min
The problem then arises when I try to execute this script with Python file.py. Python then complains with the folliwing NameError:
Traceback (most recent call last):
File "file.py", line 3, in <module>
print datetime.datetime.min
NameError: name 'datetime' is not defined
This actually happens also if I try to make the same statements (import and print) directly from the Python shell.
Shouldn't the datetime module be automatically imported in the precise moment that I call import project?
Thanks a lot in advance.
The datetime module is only imported into the project namespace. So you could access it as project.datetime.datetime.min, but really you should import it into your script directly.
Every symbol (name) that you create in your project.py file (like your Project class) ends up in the project namespace, which includes things you import from other modules. This isn't as inefficient as it might seem however - the actual datetime module is still only imported once, no matter how many times you do it. Every time you import it subsequent to the first one it's just importing the names into the current namespace, but not actually doing all the heavy lifting of reading and importing the module.
Try thinking of the import statement as roughly equivalent to:
project = __import__('project')
Effectively an import statement is simply an assignment to a variable. There may be some side effects as the module is loaded, but from inside your script all you see is a simple assignment to a name.
You can pull in all the names from a module using from project import *, but don't do that because it makes your code much more brittle and harder to maintain. Instead either just import the module or exactly the names you want.
So for your code something like:
import datetime
from project import Project
is the sort of thing you should be doing.

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