简体   繁体   English

Python-有时将包模块用作独立包时导入包内?

[英]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. 其中class2class1导入一些东西,但是if __name__ == '__main__'都使用我各自运行的类, if __name__ == '__main__'每个东西都有自己的东西。 But then, I have a second project which creates a subclass of each of the classes from project1 . 但是然后,我有第二个项目,该项目创建了project1中每个类的子类。 So I would like project1 to be a package, so that I can import it into project2 nicely: 所以我希望project1是一个程序包,以便可以将其很好地导入到project2

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 . 如果我将project1打包,则在class2.py我想使用from project1.class1 import class1来导入class1.py代码。 This makes project2 code run correctly. 这将使project2代码正确运行。 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). 但是现在,当我尝试不将project1用作程序包,而只是直接从该目录中运行代码时, project1代码将失败(因为它不知道project1是什么)。 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 . 如果我将它设置为project1直接在该目录中工作(即, class2的导入from class1 import Class1 ),则在尝试将project1用作project2的包时,此导入失败。

Is there a way to have it both ways (use project1 both as a package and not as a package)? 有没有办法同时使用它(将project1既用作程序包又不用作程序包)? 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 . 只是为了澄清,问题来了,因为subclass2导入了class2 ,而后者又导入了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. 根据class2导入class1的方式,导入将从project2project1失败,因为一个人将project1视为包,而另一人则将其视为工作目录。

EDIT 2 编辑2

I'm using Python 3.5. 我正在使用Python 3.5。 Apparently this works in Python 2, but not in my current version of python. 显然,这适用于Python 2,但不适用于我当前的python版本。

EDIT 2: Added code to class2.py to attach the parent directory to the PYTHONPATH to comply with how Python3 module imports work. 编辑2:将代码添加到class2.py,以将父目录附加到PYTHONPATH,以符合Python3模块导入的工作方式。

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

Removed relative import of Class1. 删除了Class1的相对导入。

Folder structure: 资料夹结构:

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

project2/project1/class1.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 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 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. 通过此设置,class1、2和3中的每一个都可以作为独立脚本运行。

You could run class2.py from inside the project2 folder, ie with the current working directory set to the project2 folder: 您可以从project2文件夹中运行class2.pyproject2当前工作目录设置为project2文件夹:

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

On windows that would look like this: 在看起来像这样的Windows上:

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

Alternatively you could modify the python path inside of class2.py : 或者,您可以修改class2.py内部的python路径:

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

from project1.class1 import class1

Or modify the PYTHONPATH environment variable similarly. 或类似地修改PYTHONPATH环境变量。

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 : 为了能够扩展您的项目并从subclass2.py导入subclass1.py某些内容,您应该考虑始终使用project2开始导入路径,例如在class2.py

from project2.project1.class1 import class1

Ofcourse you would need to adjust the methods I just showed to match the new path. 当然,您需要调整我刚刚显示的方法以匹配新路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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