Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
609 views
in Technique[技术] by (71.8m points)

python 3.x - How to import my own modules the elegant way?

I am struggling with a dummy question about importing classes from another sub-directory and I can’t find satisfying solution. Here is the context: I have a root folder, let’s call it project, that contains two sub folders, called app and test.

In app, I have my classes files, class1.py and so on. In test, I have test_class1.py to hold my unit test class. Seems to be some standard folder structure to me. How do I import class1 from test_class1.py? So far I append ‘../app’ to my sys.path but it looks so ugly to me! I tried from ..app import class1 and so many other combinations unsuccessfully.

Second question: Are __init__.py still needed in python 3.6+? Thanks for your help

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

1/ Regarding your first question, based on my own experience, I would structure the project as follow:

project/
  app/
   class1.py
   __init__.py
   ...
  test/
   context.py
   test_class1.py
   __init__.py
   ...
  setup.py
  ...

Obviously, these test modules must import your packaged module to test it. You can do this a few ways:

  • Expect the package to be installed in site-packages.
  • Use a simple (but explicit) path modification to resolve the package properly.

I highly recommend the latter. Requiring a developer to run setup.py develop to test an actively changing codebase also requires them to have an isolated environment setup for each instance of the codebase.

To give the individual tests import context, create a tests/context.py file:

context.py* should bootstrap the testing context as follow:

import sys
import os

sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import app
from app import class1
... 

Then in your test_class1.py file, I would import the tested Class as follow:

from unittest import TestCase
from .context import class1  # or from context.class1 import MyClass

class TestClass1(TestCase):

    def setUp(self):
        self.to_be_tested = class1.MyClass() # or MyClass()

2/ Regarding your second question about __init__.py file being needed or not in python 3.6+, I let you read the following existing answer: Is __init__.py not required for packages in Python 3?

Possible Interesting references:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...