Import into a Python project with exercises

I have a Python project with the following directory structure:

  / (some files)
 / model / (python files)
 / tools / (more python files)
 ...

So, I have Python files in a pair of subdirectories, and there are some dependencies between directories: the tools are used by the model, etc. Now my problem is that I want to make doctrines for models and tools , and I want to be able to run tests from the command line as follows: ./model/car.py . I can do this job, but only with a dirty template. I would like to know what is in the right way, or are there any?

Question : How do I write my import?

Thanx. Here is an example ...

Contents tools / tool.py :

#!/usr/bin/env python """ >>> is_four(21) False >>> is_four(4) True """ def is_four(val): return val == 4 if __name__ == '__main__': import doctest doctest.testmod() 

... and model / car.py :

 #!/usr/bin/env python """ >>> car = Car() >>> car.ok() True """ from tools.tool import * class Car(object): def __init__(self): self.tire_count = 4 def ok(self): return is_four(self.tire_count) if __name__ == '__main__': import doctest doctest.testmod() 

Adding the following lines to the top of car.py, it works, but it doesn’t look very good .:

 if __name__ == '__main__': import sys import os sys.path.append(os.path.abspath(os.path.dirname('..'))) 
+4
source share
3 answers

What you are trying to do is relative imports. It works fine in Python, but at the module level, and not at the file system level. I know this is confusing.

This means that if you run the script in a subdirectory, it does not see the upper sections, because to run the script, the module root is the current director: there is no top module.

So what is relative imports for?

Well, the module in the module import cars subdirs in the upper rows, if they themselves are imported from the upper level.

In your case, this means that you must run your scripts from "/" so that it becomes the root of the module, and submodules are allowed to use relative imports.

A possible solution to your problem is to remove the if __name__ == "__main__" block and create /tests.py:

 import doctest from model import car from tools import tool doctest.testmod(car) doctest.testmod(tool) 

Then run all the tests as well.

Ultimately, you'll want to automate the process, a simple solution is to use unittest so you can create test packages and just add the names of the modules you want to test:

 import unittest import doctest modules = ("model.car", "tools.tool") suite = unittest.TestSuite() for mod in modules: suite.addTest(doctest.DocTestSuite(mod)) runner = unittest.TextTestRunner() runner.run(suite) 

Another solution (recommended) is to use a tool such as nose that automates this for you.

 easy_install nose nosetests --with-doctest # done :-) 

And by the way, avoid from x import * . This works for fast scripts, but when your program grows, you really need to explicitly specify what you are importing. Either import x , or from x import y

+1
source

Use packages. Add the __init__.py file to the working directory and all the subfolders, then your import will look in the parent directories if it does not find the module in the current directory.

See http://www.network-theory.co.uk/docs/pytut/Packages.html

Also this question is a duplicate:

Import module from relative path

+1
source

Do not frob sys.path this way. Instead, use $PYTHONPATH to force the base directory when calling python or use python -m model.car from this directory.

0
source

Source: https://habr.com/ru/post/1302997/


All Articles