简体   繁体   中英

Python - Intra-package importing when package modules are sometimes used as standalone?

Sorry if this has already been answered using terminology I don't know to search for.

I have one project:

project1/
    class1.py
    class2.py

Where class2 imports some things from class1 , but each has its own if __name__ == '__main__' that uses their respective classes I run frequently. But then, I have a second project which creates a subclass of each of the classes from project1 . So I would like project1 to be a package, so that I can import it into project2 nicely:

project2/
    project1/
        __init__.py
        class1.py
        class2.py
    subclass1.py
    subclass2.py

However, I'm having trouble with the importing with this. If I make project1 a package then inside class2.py I would want to import class1.py code using from project1.class1 import class1 . This makes project2 code run correctly. But now when I'm trying to use project1 not as a package, but just running code from directly within that directory, the project1 code fails (since it doesn't know what project1 is). If I set it up for project1 to work directly within that directory (ie the import in class2 is from class1 import Class1 ), then this import fails when trying to use project1 as a package from project2 .

Is there a way to have it both ways (use project1 both as a package and not as a package)? If there is a way, is it a discouraged way and I should be restructuring my code anyway? Other suggestions on how I should be handling this? Thanks!

EDIT

Just to clarify, the problem arrises because subclass2 imports class2 which in turn imports class1 . Depending on which way class2 imports class1 the import will fail from project2 or from project1 because one sees project1 as a package while the other sees it as the working directory.

EDIT 2

I'm using Python 3.5. Apparently this works in Python 2, but not in my current version of python.

EDIT 2: Added code to class2.py to attach the parent directory to the PYTHONPATH to comply with how Python3 module imports work.

import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

Removed relative import of Class1.

Folder structure:

project2
  - class3.py
  - project1
    - __init__.py
    - class1.py
    - class2.py

project2/project1/class1.py

class Class1(object):
    def __init__(self):
        super(Class1, self).__init__()
        self.name = "DAVE!"

    def printname(self):
        print(self.name)

def run():
    thingamy = Class1()
    thingamy.printname()

if __name__ == "__main__":
    run()

project2/project1/class2.py

import sys
import os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from class1 import Class1

class Class2(Class1):
    def childMethod(self):
      print('Calling child method')

def run():
    thingamy = Class2()
    thingamy.printname()
    thingamy.childMethod()

if __name__ == "__main__":
    run()

project2/class3.py

from project1.class2 import Class2
from project1.class1 import Class1

class Class3(Class2):
    def anotherChildMethod(self):
      print('Calling another child method')

def run():
    thingamy = Class3()
    thingamy.printname()
    thingamy.anotherChildMethod()

if __name__ == "__main__":
    run()

With this setup each of class1, 2 and 3 can be run as standalone scripts.

You could run class2.py from inside the project2 folder, ie with the current working directory set to the project2 folder:

user@host:.../project2$ python project1/class2.py

On windows that would look like this:

C:\...project2> python project1/class2.py

Alternatively you could modify the python path inside of class2.py :

import sys
sys.path.append(".../project2")

from project1.class1 import class1

Or modify the PYTHONPATH environment variable similarly.

To be able to extend your project and import for example something in subclass1.py from subclass2.py you should consider starting the import paths always with project2 , for example in class2.py :

from project2.project1.class1 import class1

Ofcourse you would need to adjust the methods I just showed to match the new path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM