Nested function causing troubles - python

I've got a Python script.
I've had several functions in this script which I decided to move to a 'package' folder beside the main script.
In this folder, I created a *.py file where I put all my functions.
I've placed an empty init.py near this file within the 'package' folder.
When starting the code of my main script with:
from package_folder.my_functions import *
the script works well when calling every functions from that file.
But when trying to import it directly:
import package_folder.my_functions
it doesn't seems to work as well as with the above technique.
The cause seems to be the fact that in the file wellmy_functions.py, I have a function that needs an other one, declared previously in that file.
I had this obscure error on that function that needs an other one:
TypeError: 'NoneType' object is not callable
Is this permissible and if not, how to manage this case?

It's generally not a good idea to use from module import *. Wildcard importing leads to namespace pollution; you imported more names than you need and if you accidentally refer to an imported name you may not get the NameError you wanted.
Also, if a future version of the library added additional names, you could end up masking other names, leading to strange bugs still:
Example
from my_mod1 import func1
from my_mod2 import *
If you upgrade my_mod2 and it now includes a my_mod2.func1 it'll replace the my_mod1.func1 import in the 1st line.

Related

calling a function defined in different python script within working folder

I am trying to call a function defined in file lidar_source_code.py from my main script py_lidar_depressions.py. There are numerous sources which explain how to do this such as this one, however When I attempt this the error ModuleNotFoundError: No module named 'lidar_source_code' is returned. I must say that I am not surprised at this error as at no point did I point to where the file is located even though relevant tutorials do not seem to suggest the need to. The code to import the file and all of the defined functions was as simple as the following.
from lidar_source_code import *
Is there something I am missing here. Am I correct that one must first define the path of the function containing file before importing it?
Thanks

What does a dot denote in an import statement?

Could anyone please explains what from .object import object means?
I know that everything extends object just like in Java.But what does .object means?
I saw this piece of code in the source code in psycopg2:
from .object import object
class cursor(object):
pass
That's the new syntax for explicit relative imports. It means import from the current package.
Without the ., if you had a file _object.py for some indecipherable reason next to your main script, object would break. With the ., it ensures it gets its own module.
The thing that defines what a "current package" is that it should say from where the importing package is. It basically means the current namespace or package directory.
Hope this helps!
From the docs:
One leading dot means the current package where the module making the import exists. Two dots means up one package level. Three dots is up two levels, etc. So if you execute from . import mod from a module in the pkg package then you will end up importing pkg.mod. If you execute from ..subpkg2 import mod from within pkg.subpkg1 you will import pkg.subpkg2.mod. The specification for relative imports is contained within PEP 328.
The dot is basically telling the program to search in the current directory before looking at the files in your python path. If object exists in both the current directory and your python path, only the one from the former will be imported.

Unable to split up large Python module

In Python 2.7, I'm getting
'module' has no attribute
, and/or
'name' is not defined
errors when I try to split up a large python file.
(I have already read similar posts and the Python modules documentation)
Say you have a python file that is structured like this:
<imports>
<50 global variables defined>
<100 lengthy functions that each use most or all of the globals
defined above, and also call each other>
<main() that calls some of the functions and uses the globals>
So I can easily categorize groups of functions together, create a python file for each group, and put them there. The problem is whenever I try to call any of them from the main python file, I get the errors listed above. I think the problem is related to circular dependencies. Since all of the functions rely on the globals, and each other, they are circularly dependent.
If I have main_file.py, group_of_functions_1.py, and group_of_functions_2.py,
main_file.py will have:
import group_of_functions_1.py
import group_of_functions_2.py
and group_of_functions_1.py will have
import main_file.py
import group_of_functions_2.py
and group_of_functions_2.py will have
import main_file.py
import group_of_functions_1.py
Regardless of whether I use "import package_x" or "from package_x import *" the problem remains.
If I take the route of getting rid of the globals, then most of the functions will have 50 parameters they will be passing around which then also need to be returned
What is the right way to clean this up?
(I have already read similar posts and the Python modules documentation)
One of the sources of your errors is likely the following:
import group_of_functions_1.py
import group_of_functions_2.py
When importing, you don't add .py to the end of the module name. Do this instead:
import group_of_functions_1
import group_of_functions_2

Python: Importing an "import file"

I am importing a lot of different scripts, so at the top of my file it gets cluttered with import statements, i.e.:
from somewhere.fileA import ...
from somewhere.fileB import ...
from somewhere.fileC import ...
...
Is there a way to move all of these somewhere else and then all I have to do is import that file instead so it's just one clean import?
I strongly advise against what you want to do. You are doing the global include file mistake again. Although only one module is importing all your modules (as opposed to all modules importing the global one), the remaining point is that if there's a valid reason for all those modules to be collected under a common name, fine. If there's no reason, then they should be kept as separate includes. The reason is documentation. If I open your file, and see only one import, I don't get any information about what is imported and where it comes from. If on the other hand, I have the list of imports, I know at a glance what is needed and what not.
Also, there's another important error I assume you are doing. When you say
from somewhere.fileA import ...
from somewhere.fileB import ...
from somewhere.fileC import ...
I assume you are importing, for example, a class, like this
from somewhere.fileA import MyClass
this is wrong. This alternative solution is much better
from somewhere import fileA
<later>
a=fileA.MyClass()
Why? two reasons: first, namespacing. If you have two modules having a class named MyClass, you would have a clash. Second, documentation. Suppose you use the first option, and I find in your code the following line
a=MyClass()
now I have no idea where this MyClass comes from, and I will have to grep around all your files in order to find it. Having it qualified with the module name allows me to immediately understand where it comes from, and immediately find, via a /search, where stuff coming from the fileA module is used in your program.
Final note: when you say "fileA" you are doing a mistake. There are modules (or packages), not files. Modules map to files, and packages map to directories, but they may also map to egg files, and you may even create a module having no file at all. This is naming of concepts, and it's a lateral issue.
Of course there is; just create a file called myimports.py in the same directory where your main file is and put your imports there. Then you can simply use from myimports import * in your main script.

python NameError: name '<anything>' is not defined (but it is!)

Note: Solved. It turned out that I was importing a previous version of the same module.
It is easy to find similar topics on StackOverflow, where someone ran into a NameError. But most of the questions deal with specific modules and the solution is often to update the module.
In my case, I am trying to import a function from a module that I wrote myself. The module is named InfraPy, and it is definitely on sys.path. One particular function (called listToText) in InfraPy returns a NameError, but only when I try to import it into another script. Inside InfraPy, under if __name__=='__main__':, the listToText function works just fine. From InfraPy I can import other functions with no problems. Including from InfraPy import * in my script does not return any errors until I try to use the listToText function.
How can this occur?
How can importing one particular function return a NameError, while importing all the other functions in the same module works fine?
Using python 2.6 on MacOSX 10.6, also encountered the same error running the script on Windows 7, using IronPython 2.6 for .NET 4.0
Thanks.
If there are other details you think would be helpful in solving this, I'd be happy to provide them.
As requested, here is the function definition inside of InfraPy:
def listToText(inputList, folder=None, outputName='list.txt'):
'''
Creates a text file from a list (with each list item on a separate line). May be placed in any given folder, but will otherwise be created in the working directory of the python interpreter.
'''
fname = outputName
if folder != None:
fname = folder+'/'+fname
f = open(fname, 'w')
for file in inputList:
f.write(file+'\n')
f.close()
This function is defined above and outside of if __name__=='__main__':
I've tried moving InfraPy around in relation to the script. The most baffling situation is that when InfraPy is in the same folder as the script, and I import using from InfraPy import listToText, I receive this error: NameError: name listToText is not defined. Again, the other functions import fine, they are all defined outside of if __name__=='__main__': in InfraPy.
This could happen if the module has __all__ defined
Alternatively there could be another version of the module in your path that is getting imported instead of the one you are expecting
Is the NameError about listToText or is it something inside the function causing the exception?
In addition the __all__ variable gnibbler mentioned you could also have a problem with a InfraPy.pyc file lying around somewhere.
I'd recommend putting a import pdb;pdb.set_trace() first in the InfraPy.py file to make sure you are in the right file, and step through the definition of InfraPy.py to see what is happening. If you don't get a breakpoint, you are importing another file than you think.
You can also dir(InfraPy) after importing it, and check which file you are actually importing with InfraPy.__file__.
Can't think of any more import debugging hints right now. ;-)

Categories

Resources