Python Idle and Terminal Import Differences - python

I just started using Python and I have a question about idle vs terminal.
In idle, I made a file called Robot.py
I have a class called Robot
class Robot(object)
def __init__(self,x,y):
#some code here etc...
def HelloWorld()
print "Hello World!"
I have another file called testrobot.py, which looks like so:
import Robot
r = Robot(1,4)
In idle, I am able to successfully create a Robot object when I run testrobot.py. However in terminal, it gives an error Message NameError: Robot is not defined
I'm not sure how to run my program in terminal.
Also:
How can I call my HelloWorld() function which is in Robots.py but not of the class Robot in an external file (such as testrobot.py)?
Thanks in advance!

When you load and run scripts in IDLE, they are automatically loaded for the interpreter. That means that as soon as you run the script in IDLE, the Python shell already has those types defined.
When you want to run it from outside of IDLE, i.e. without running the module first, you need to import your Robot from that module. To do that, you import the module, not the type:
import Robot
myRobot = Robot.Robot(...)
Or, if you want to use Robot directly, you need to use the from ... import syntax:
from Robot import Robot
myRobot = Robot(...)
Similarily, you can call your function by using Robot.HelloWorld in the first case, or directly if you add HelloWorld to the import list in the second case:
from Robot import Robot, HelloWorld
myRobot = Robot(...)
HelloWorld()
As you can see, it is generally a good idea to name your files in lower case, as those are the module names (or “namespaces” in other languages).

You are trying to create a class of an import, not the class imported.
You are trying to import a file called Robot.py with that import statement. To import your robot class you will have to type import Robot and then write Robot.Robot(1,4) to create an object of it. Alternatively you can import all references from the file: from Robot import * and then write Robot(1,4).
The reason it will work with IDLE is that it basically imports everything from the file you run, allowing you use the methods and classes in that file.

Related

Having trouble with imports in Python

I use Python 2.7. I'm trying to run my UI-automation script, but I got ImportError.
I have at least 30 Classes with methods. I want to have these methods in each and any class that's why I created BaseClass(MainClass) and created objects of all my classes. Please advise what should I do in this case or how I can solve this problem.
Here the example what similar to my code.
test_class/baseclass.py
from test_class.first_class import FirstClass
from test_class.second_class import SecondClass
class MainClass:
def __init__(self):
self.firstclass = FirstClass()
self.secondclass = SecondClass()
test_class/first_class.py
from test_class.baseclass import MainClass
class FirstClass(MainClass):
def __init__(self):
MainClass.__init__(self)
def add_two_number(self):
return 2 + 2
test_class/second_class.py
from test_class.baseclass import MainClass
class SecondClass(MainClass):
def __init__(self):
MainClass.__init__(self)
def minus_number(self):
return self.firstclass.add_two_number() - 10
if __name__ == '__main__':
print(SecondClass().minus_number())
When I run the last file I get this error
Traceback (most recent call last):
File "/Users/nik-edcast/git/ui-automation/test_class/second_class.py", line 1, in <module>
from test_class.baseclass import MainClass
File "/Users/nik-edcast/git/ui-automation/test_class/baseclass.py", line 1, in <module>
from test_class.first_class import FirstClass
File "/Users/nik-edcast/git/ui-automation/test_class/first_class.py", line 1, in <module>
from test_class.baseclass import MainClass
ImportError: cannot import name MainClass
check this line: from test_class.baseclass import MainClass -> it seems like all other imports had a '_' between the names like second_class. So try maybe to write base_class. who knows might work
Are you proabably running your code like python test_class/second_class.py. If you just do this then python will think the base directory to find modules is ./test_class. So when you import the test_class package python will start looking for a folder called ./test_class/test_class to find the sub-modules. This directory doesn't exist and so the import fails. There are several ways that you can tell python how to correctly find your modules.
Using PYTHONPATH
One way to get around this is to set PYTHONPATH before starting python. This is just an environment variable with which you can tell python where to look for your modules.
eg.
export PYTHONPATH=/path/to/your/root/folder
python test_class/second_class.py
Using the -m switch for python
Be default python treats the directory of the main module as the place to look for other modules. However, if you use -m python will fall back to looking in the current directory. But you also need to specify the full name of the module you want to run (rather than as a file). eg.
python -m test_class.second_class
Writing a root entry point
In this we just define your main module at the base level (the directory that contains test_class. Python will treat this folder as the place to look for user modules and will find everything appropriately. eg.
main.py (in /path/to/your/root/folder)
from test_class.second_class import SecondClass
if __name__ == '__main__':
print(SecondClass().minus_number())
at the command line
python main.py
You could try importing the full files instead of using from file import class. Then you would only need to add the file name before referencing something from another file.

Python - Modelica connection fails due to import error

I am trying to connect Modelica and Python using the Python27 block, provided by the Berkeley Simulations Lab:
http://simulationresearch.lbl.gov/modelica
I use this block to call a Python function:
def Test2(WriteValues):
''' Connection Test - Works if started from Dymola
'''
#Doing nothing and returning the input
ReturnList=WriteValues
return (ReturnList)
works perfectly.
Now I need to import some modules
#Importing Python modules works in general
import sys
import thread
import time
works aswell
Only now I want to import a module that is not part of Python but a site-package:
def Test1(WriteValues):
'''Connection Test - Doesnt work if started from Dymola
'''
#Importing some Bacpypes Module
#Path is by default C:\Python27\Lib\site-packages\BACpypes-0.7-py2.7.egg\bacpypes
#My os is win7
from bacpypes.core import run
#Doing nothing and returning the input
ReturnList=WriteValues
return (ReturnList)
This does not work. It does not matter if I import the BACpypes module inside a function or globally - the error is always
'module' object has no attribute 'argv'
Colleagues pointed me to the idea that it might be related to a multiple import problem. The function is being called by Modelica every 10 seconds (real-time-simualtion).
If I call the function Test1 outside of Modelica, there is no problem. It only fails using the Python27 block!
Does anyone have an idea about how to make the BACpypes import work?
UPDATE 2013-10-16:
I printed out the value of sys.argv for the script excecution in the Python directory and an excecution from Modelica.
sys.argv from Python directory:
['C:\\Python27\\Testcon.py']
sys.argv if function is called from inside Modelica:
['modpython']
Might this in any way be related to the error message I get?
The bug is caused because bacpypes uses sys.argv but the Python interpreter did not call PySys_SetArgv.
This will be fixed in the next version of the Modelica Buildings library, see https://github.com/lbl-srg/modelica-buildings/issues/191

Linking Python Files Assistance

I understand how to actually link python files, however, i don't understand how to get variable's from these linked files. I've tried to grab them and I keep getting NameError.
How do I go about doing this? The reason i want to link files is to simply neaten up my script and not make it 10000000000 lines long. Also, in the imported python script, do i have to import everything again? Another question, do i use the self function when using another scripts functions?
ie;
Main Script:
import sys, os
import importedpyfile
Imported Py File
import sys, os
I understand how to actually link python files, however, i don't
understand how to get variable's from these linked files. I've tried
to grab them and I keep getting NameError.
How are you doing that? Post more code. For instance, the following works:
file1.py
#!/usr/bin/env python
from file2 import file2_func, file2_variable
file2_func()
print file2_variable
file2.py:
#!/usr/bin/env python
file2_variable = "I'm a variable!"
def file2_func():
print "Hello World!"
Also, in the imported python script, do i have to import everything
again?
Nope, modules should be imported when the python interpreter reads that file.
Another question, do i use the self function when using another
scripts functions?
Nope, that's usually to access class members. See python self explained.
There is also more than one way to import files. See the other answer for some explanations.
I think what you are trying to ask is how to get access to global vars from on .py file without having to deal with namespaces.
In your main script, replace the call to import importedpyfile to say this instead
from importedpyfile import *
Ideally, you keep the code the way you have it. But instead, just reference those global vars with the importedpyfile namespace.
e.g.
import importedpyfile
importedpyfile.MyFunction() # calls "MyFunction" that is defined in importedpyfile.py
Python modules are not "linked" in the sense of C/C++ linking libraries into an executable. A Python import operation creates a name that refers to the imported module; without this name there is no (direct) way to access another module.

Import class without executing .py it is in?

I defined a class called Prof in a script called AddPntCode90_27.py. It opens some files, does some math, creates output files and so. Now I want to re-use the class for another programme. But as AddPntCode90_27.py is not a module it always executes the script instead of just importing the class.
I did from AddPntCode90_27 import * as well as from AddPntCode90_27 import Prof.
I am familiar with this article. So my questions are:
is it bad practice to define a class within a script like this? Should I always keep them in a separated file?
is there, however, a way to import just the class and its methods without executing the script it is defined in?
Ah, I'm running Python 2.7.
The way to do what you want is to use an if __name__ == "__main__" block. See this question.
It's perfectly fine to define classes in scripts, but you cannot import the class without executing the script, because it is only by executing the script that you define the class. Class definitions are not a "compile-time declaration" in Python; they are executed in order just like everything else in the module. You should use an if __name__=="__main__" block to protect code that you don't want to be run when you import your file as a module.
You should the if __name__="__main__: idiom to check whether Python is running the code or the code is being imported as a module.

How to link multiple scripts?

I would like to separate my functions into different files like I do with c++ (a driver file and a file for different categories of functions that I end up linking together upon compilation).
Let's suppose I want to create a simple 'driver' file which launches the main program and a 'function' file which includes simple functions which are called by the driver and other functions within the 'function' file.
How should I do this? Since python is not compiled, how do I link files together?
You can import modules. Simply create different python files and import them at the start of your script.
For example I got this function.py file :
def func(a, b):
return a+b
And this main.py file:
import function
if __name__ == "__main__":
ans = function.func(2, 3)
print(ans)
And that is it! This is the official tutorial on importing modules.
You can import any Python file simply by typing:
import filename
But in this case you have to type the file name each time you want to use it. For example, you have to use filename.foo to use the specific function foo inside that file. However, you can also do the following:
from function import *
In this case all you have to do is to directly type your commands without filename.
A clear example:
If you are working with the Python turtle by using import turtle then each time you have to type turtle.foo. For example: turtle.forward(90), turtle.left(90), turtle.up().
But if you use from turtle import * then you can do the same commands without turtle. For example: forward(90), left(90), up().
At the beginning of driver.py, write:
import functions
This gives you access to attributes defined in functions.py, referenced like so:
functions.foo
functions.bar(args)
...

Categories