Howto import a function with python - python

I'm developing a Python application for the GAE.
The application consists of a bunch of classes and functions which are at the moment all in the same file main.py.
The application is running without problems.
Now, I want to refactor the application and outsource all the classes. Every class should be in her own file. The files shall be arranged in directories like this:
main.py
/directory1/class1.py
/directory1/class2.py
/directory2/class1.py
My problem is that inside these outsourced classes, I cannot use the functions of main.py.
I tried this inside the class-files.
from main import name_of_function
But the compiler says
from main import name_of_function
ImportError: cannot import name name_of_function
What did I wrong?
The name of the funktion is login. Maybe this causes the problem?

Try moving the extra functions from main.py into a separate file.
main.py
library.py # contains login() and other functions from main
/directory1/class1.py
/directory1/class2.py
/directory2/class1.py

Sometimes it is good to leave classes in same module not separate without purpose if they belong together.
The problem of using function from main is sign that you should refactor one module say common_utils.py out of those functions and separate it from main. You can import that to your modules, which use those. Do not think classes only think whole use case.
If you could give pseudo code of your program's logic, we could check the refactoring better together.

Related

Declaring variables for multiple scripts and best practices

What is the best way to put variables in python for multiple scripts?
I have the following scripts:
main.py: This script to declare common variables for one.py, two.py, and three.py. Also takes input from the user in interactive way and from the defined input file.
config.py: This script has all three scripts configurations inputs like ip-adress, ports details. etc.
one.py: I have written this script with class and it take inputs from main.py and config.py.
two.py: I have written this script with class and it take inputs from main.py and config.py.
three.py: I have written this script with class and it take inputs from main.py and config.py.
run.py: This script loads class objects for the one.py, two.py, and three.py and calls the functions defined in them.
main.py
list1 = []
a = "common for one.py,two.py and three.py"
one.py
import main
main.list1.append("1")
two.py
import main
main.list1.append("2")
three.py
import main
main.list1.append("3")
Running script:
run.py
import main
import one
import two
import three
# start performing
#call one script functions
#call two script functions
#call three script functions
I need some suggestions from you.
Am I am doing it in right way?
Will my scripts be easy for future maintenance?
Since I am putting variable list1 in main.py. It will first
appending some value in one.py and then two.py is going to access it.
My doubt is two.py is importing main.py in this case it does not
overwrite with empty list value? I have tested it, and it works fine.
But I still want to take your suggestions for best practices.
Yes, I think what you're doing is basically OK. I would rename a couple of the scripts to better indicate their roles: I would rename run.py and make it main.py, and make what you called main.py something like common.py. However, for the sake of discussion, I'll use the script names you have in your question.
You don't have to worry about what's in your main.py reinitializing list1 variable every time it's imported. That's because the results of importing modules are "cached" in sys.modules and the top-level code in them only executes the first time they're imported. If another script imports one of them again, the results of the first time saved in cached version is used. You can think of loaded modules as "singleton" instances of a module class (which in fact they are, see types.ModuleType).
If there's a dependency in your run.py that the modules one, two, and three are imported in a certain order, then I would import them all in your main module, so other scripts don't have to worry about it (the ordering). That way other scripts can just import whichever ones they want to use.
The above is not to say your design couldn't be improved. It looks like you're basically using global variables, which have long been considered a "bad thing" for a number of reasons (see Global Variables Are Bad). To avoid that, the direct use of list1 would need to be replaced with an instance of some new custom class with it's lifetime and access to it handled indirectly via methods defined in the class after explicitly creating an instance of it. This instance would then need to be passed as argument to any function or method that needed use or otherwise do something with or to the instance.
This doesn't look easy to maintain, since the values appended to the list only happen upon calling the import in main. Import them in the wrong order, or forget to import one of them, and you will get unexpected results.
In general, it is fine to share variables between scripts, but the various modules should not edit the values of the shared variables, rather, each module should be solely responsible for the values of its variables.

Python: Calling a function from a file that has current file imported

I tried searching around but didn't seem to find an answer to my problem, so I'm sorry if I missed something and it actually has been answered before.
So basically I have main.py and another file called check.py (both in same directory)
In my main.py I have:
from check import checkfunction
I have a small function inside main.py that I MUST call inside check.py, but I can't seem to get this import working on my check.py:
from main import mainfunction
How can I get the mainfunction to work inside check.py?
Thanks!
You've got a design with a circular dependency which is usually a bad thing as your two python modules are tightly coupled.
Consider refactoring your code. But if you must stick with your design please see the following SO question for more info on how circular imports work in Python and the various gotchas to look out for.
Several options:
Move the common function to a module imported by both other modules.
Merge both modules into one.
Pass the function from main to the code that needs to call it.
Monkey patch the function into the check module after importing it.
Refactor the whole thing so that you don't have circular dependencies.
If you actually explained why you have this design, someone could possibly propose a better way.

when does import module at bottom of file

when I read a file riak-python-client/riak/riak_object.py. At the bottom of the file, I saw this
from mapreduce import *
what's it use for? Why just import at the top of the file.
This is designed to put all of the module mapreduce in the riak_object namespace. If you put this import at the top of riak_object.py, then there would be an error because mapreduce imports RiakObject from riak_object, which is not defined yet.
You can use an import at any point in a file; you just have to make sure you don't try to use stuff from the module until after you have imported it.
If this is actually the last line run in the file, than it wouldn't serve any purpose. If it at the bottom of the file but inside some function or method, it might mean that that function/method is not run frequently and the author didn't want the overhead of importing mapreduce every time the program is run.
I don't know the specific reasoning for that project, but just put the imports at the top of your file. This makes the dependencies far easier to track, and it is recommended by Python's style guide.
Technically, the code that is imported by an import statement is only available after the import statement has been executed. This means that when you put it at the bottom of your file, you can't use anything imported there in that file (on module level). Functions in that file can use the imports... but it's just bad practice.
The only reason would be that riak_object (which doesn't seem to require anything from mapreduce?) is bringing into its namespace all the values (or those specified by __all__) from mapreduce as some kind of convenience.

Import a python script in MainFolder to another script in MainFolder/file

I an writing an app to record data given by the user, calculate and print out bills. I have written a script usage.py in MainFolder and want to pull its methods or functions in MainFolder/file/MainFile.py . I have already used the methods or functions in usage.py in MainWin.py
The scripts are in the 3 py extensions are pasted here
How can I use them in methods in MainFolder/usage.py in MainFolder/file/MainFile.py ?
If you make the folder a package that will allow you to use the methods in either location. But, to give further advice it would make more sense to move the methods that are in usage.py into the MainFile.py from a design standpoint. It doesn't make a lot of sense to use functions in a top level file in a nested file.
If you make it a module you can use:
from some.package.usage import policySize
Module documentation:
http://docs.python.org/tutorial/modules.html

How to reference object properties in another module

I am relatively new to Python having used C# for many years and I'm hoping someone can help me with this question. I have a module called actuators.py that contains a number of classes for defining properties and methods for the servos I use in a robot project. In another module called robot.py, I instantiate my actuators like this:
import actuators as Actuators
myActuators = Actuators.AllActuators()
This allows me to access the properties of my servos as long as I am in the robot.py module. For example, I can write:
print myActuators.HeadTilt.MinPosition
to get the minimum value allowed for the servo that tilts the robot's head. So far so good.
Now I want to access these same values in a separate thread that is defined by a different module called tilt_head.py. I assume I need to import a reference to the robot.py module, but doing this ends up re-executing all the code in robot.py whereas all I really want is a static reference to the myActuators object. And I can't use
from robot.py import myActuators
because myActuators is not a module.
In C#, I would do this using a declaration like this:
public static Actuators myActuators;
which then allows me to reference myActuators in any other file within my project. Is there a way to do something similar in Python? If you need my actual code, I will be happy to post it.
Thanks!
And I can't use
from robot.py import myActuators
because myActuators is not a module.
But myActuators doesn't need to be a module. You can do exactly that. (Though you'll want to use just robot rather than robot.py)
http://docs.python.org/reference/simple_stmts.html#import
As well:
http://docs.python.org/tutorial/modules.html#more-on-modules
"A module can contain executable statements as well as function definitions. These statements are intended to initialize the module. They are executed only the first time the module is imported somewhere."
So using a script that imports robot and then tilt_head, the executable stuff in robot.py will NOT be run multiple times.
Of course, if robot.py is intended to be the main module of the program, then I'd suggest going with A. Levy's answer.
You should be able to simply use:
from robot import myActuators
You can't say "from robot.py" because the name there is a module name, not a file name.
BTW: I'm not sure why you are doing import actuators as Actuators. Why do you want to change the case? Modules are most commonly lowercase.
As others have been saying, you can actually import myActuators from the robot module. To solve your problem of the code in robot being re-executed, the standard Python approach is to wrap the stand-alone code in an if __name__ == '__main__': so that it will only be executed when the module is used as a standalone app, but not when it is imported.
E.G.
# Things that are defined when robot.py is used as a module
# and when used standalone.
import actuators as Actuators
myActuators = Actuators.AllActuators()
if __name__ == '__main__':
# Stuff that you only want executed when running robot.py
Then when you want to use robot.py in another module, you should be able to do this:
from robot import myActuators
EDIT:
Actually, as JAB pointed out, I was a little confused in my explanation of conditional execution. your code won't be re-executed if you reload the module. The module loading machinery handles reloading of modules to make sure that they only get loaded and defined one time. All subsequent loads are references to the previously loaded module. If, however, you do have some steps that you only want to happen when you are running the module as a script, then you can place them in the if block and they won't be executed when you load robots from another module.
I guess it doesn't really solve your problem, though it seems like your problem was really an incorrect import syntax.
I would guess that you can access that object as robot.myActuators because it already exists in the process, inside the robot.py namespace.
Many thanks for all the answers and pointers. As it turns out, my problem was a recursive import that ended up trying to create an object more than once. By sorting out the instance creation a little more logically, I was finally able to make the problem go away.

Categories