构建python项目

构建python项目,python,python-packaging,Python,Python Packaging,我需要知道如何设置_init__.py和导入,以便构造一个python项目,在这个项目中,我可以在整个包中使用完全限定的名称 包将包含多个子包,这些子包可能包含冲突名称。包中包含的类将彼此子类,并包含对彼此的引用。项目将被生成,因此使用完全限定的名称将使生活简单得多 这个示例项目代表了我的目标结构,但只包含一个子项目,而IDE似乎很高兴它在运行时失败了 MyPackage/\uuuuuu init\uuuuuuuuuuuuuuuuuuy.py import SubPackage as SubPa

我需要知道如何设置_init__.py和导入,以便构造一个python项目,在这个项目中,我可以在整个包中使用完全限定的名称

包将包含多个子包,这些子包可能包含冲突名称。包中包含的类将彼此子类,并包含对彼此的引用。项目将被生成,因此使用完全限定的名称将使生活简单得多

这个示例项目代表了我的目标结构,但只包含一个子项目,而IDE似乎很高兴它在运行时失败了

MyPackage/\uuuuuu init\uuuuuuuuuuuuuuuuuuy.py

import SubPackage as SubPackage
from .FileB import ClassB
from .FileA import ClassA
from __future__ import absolute_import
import MyPackage


class ClassA(MyPackage.SubPackage.ClassB):
    thingA: 'MyPackage.SubPackage.ClassA'
    thingB: MyPackage.SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = MyPackage.SubPackage.ClassA()
        self.thingB = MyPackage.SubPackage.ClassB()
from __future__ import absolute_import
import MyPackage


class ClassB(object):
    nextB: 'MyPackage.SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= MyPackage.SubPackage.ClassB()
import MyPackage

x = MyPackage.SubPackage.ClassA()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassA(SubPackage.ClassB):
    thingA: 'SubPackage.ClassA'
    thingB: SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = SubPackage.ClassA()
        self.thingB = SubPackage.ClassB()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassB(object):
    nextB: 'SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= SubPackage.ClassB()
MyPackage/SubPackage/\uuuu init\uuuuu.py

import SubPackage as SubPackage
from .FileB import ClassB
from .FileA import ClassA
from __future__ import absolute_import
import MyPackage


class ClassA(MyPackage.SubPackage.ClassB):
    thingA: 'MyPackage.SubPackage.ClassA'
    thingB: MyPackage.SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = MyPackage.SubPackage.ClassA()
        self.thingB = MyPackage.SubPackage.ClassB()
from __future__ import absolute_import
import MyPackage


class ClassB(object):
    nextB: 'MyPackage.SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= MyPackage.SubPackage.ClassB()
import MyPackage

x = MyPackage.SubPackage.ClassA()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassA(SubPackage.ClassB):
    thingA: 'SubPackage.ClassA'
    thingB: SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = SubPackage.ClassA()
        self.thingB = SubPackage.ClassB()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassB(object):
    nextB: 'SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= SubPackage.ClassB()
MyPackage/SubPackage/FileA.py

import SubPackage as SubPackage
from .FileB import ClassB
from .FileA import ClassA
from __future__ import absolute_import
import MyPackage


class ClassA(MyPackage.SubPackage.ClassB):
    thingA: 'MyPackage.SubPackage.ClassA'
    thingB: MyPackage.SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = MyPackage.SubPackage.ClassA()
        self.thingB = MyPackage.SubPackage.ClassB()
from __future__ import absolute_import
import MyPackage


class ClassB(object):
    nextB: 'MyPackage.SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= MyPackage.SubPackage.ClassB()
import MyPackage

x = MyPackage.SubPackage.ClassA()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassA(SubPackage.ClassB):
    thingA: 'SubPackage.ClassA'
    thingB: SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = SubPackage.ClassA()
        self.thingB = SubPackage.ClassB()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassB(object):
    nextB: 'SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= SubPackage.ClassB()
MyPackage/SubPackage/FileB.py

import SubPackage as SubPackage
from .FileB import ClassB
from .FileA import ClassA
from __future__ import absolute_import
import MyPackage


class ClassA(MyPackage.SubPackage.ClassB):
    thingA: 'MyPackage.SubPackage.ClassA'
    thingB: MyPackage.SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = MyPackage.SubPackage.ClassA()
        self.thingB = MyPackage.SubPackage.ClassB()
from __future__ import absolute_import
import MyPackage


class ClassB(object):
    nextB: 'MyPackage.SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= MyPackage.SubPackage.ClassB()
import MyPackage

x = MyPackage.SubPackage.ClassA()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassA(SubPackage.ClassB):
    thingA: 'SubPackage.ClassA'
    thingB: SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = SubPackage.ClassA()
        self.thingB = SubPackage.ClassB()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassB(object):
    nextB: 'SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= SubPackage.ClassB()
test.py

import SubPackage as SubPackage
from .FileB import ClassB
from .FileA import ClassA
from __future__ import absolute_import
import MyPackage


class ClassA(MyPackage.SubPackage.ClassB):
    thingA: 'MyPackage.SubPackage.ClassA'
    thingB: MyPackage.SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = MyPackage.SubPackage.ClassA()
        self.thingB = MyPackage.SubPackage.ClassB()
from __future__ import absolute_import
import MyPackage


class ClassB(object):
    nextB: 'MyPackage.SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= MyPackage.SubPackage.ClassB()
import MyPackage

x = MyPackage.SubPackage.ClassA()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassA(SubPackage.ClassB):
    thingA: 'SubPackage.ClassA'
    thingB: SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = SubPackage.ClassA()
        self.thingB = SubPackage.ClassB()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassB(object):
    nextB: 'SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= SubPackage.ClassB()
错误

  File "C:\temp\Test.py", line 3, in <module>
    import GeneratedLx
  File "C:\temp\MyPackage\__init__.py", line 1, in <module>
    import Bs as Bs
  File "C:\temp\MyPackage\SubPackage\__init__.py", line 12, in <module>
    from .FileA import ClassA
  File "C:\temp\MyPackage\SubPackage\FileA.py", line 5, in <module>
    class ClassA(MyPackage.SubPackage.ClassB):
AttributeError: module 'MyPackage' has no attribute 'SubPackage'
文件“C:\temp\Test.py”,第3行,在
导入生成的lx
文件“C:\temp\MyPackage\\uuuuu init\uuuuuu.py”,第1行,在
将Bs作为Bs导入
文件“C:\temp\MyPackage\SubPackage\\uuuu init\uuuuu.py”,第12行,在
from.FileA导入类A
文件“C:\temp\MyPackage\SubPackage\FileA.py”,第5行,在
类别A(MyPackage.SubPackage.ClassB):
AttributeError:模块“MyPackage”没有属性“SubPackage”

您已经不能在
子包
级别上存在名称冲突,因此添加
MyPackage
完全是多余的,并且不能像您尝试使用它那样工作。这可能是由于名称被绑定或其他原因造成的,但最终在您需要它时不应该有实例。这样您就可以稍微编辑文件:“FileA.py”和“FileB.py”:

FileA.py

import SubPackage as SubPackage
from .FileB import ClassB
from .FileA import ClassA
from __future__ import absolute_import
import MyPackage


class ClassA(MyPackage.SubPackage.ClassB):
    thingA: 'MyPackage.SubPackage.ClassA'
    thingB: MyPackage.SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = MyPackage.SubPackage.ClassA()
        self.thingB = MyPackage.SubPackage.ClassB()
from __future__ import absolute_import
import MyPackage


class ClassB(object):
    nextB: 'MyPackage.SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= MyPackage.SubPackage.ClassB()
import MyPackage

x = MyPackage.SubPackage.ClassA()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassA(SubPackage.ClassB):
    thingA: 'SubPackage.ClassA'
    thingB: SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = SubPackage.ClassA()
        self.thingB = SubPackage.ClassB()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassB(object):
    nextB: 'SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= SubPackage.ClassB()
FileB.py

import SubPackage as SubPackage
from .FileB import ClassB
from .FileA import ClassA
from __future__ import absolute_import
import MyPackage


class ClassA(MyPackage.SubPackage.ClassB):
    thingA: 'MyPackage.SubPackage.ClassA'
    thingB: MyPackage.SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = MyPackage.SubPackage.ClassA()
        self.thingB = MyPackage.SubPackage.ClassB()
from __future__ import absolute_import
import MyPackage


class ClassB(object):
    nextB: 'MyPackage.SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= MyPackage.SubPackage.ClassB()
import MyPackage

x = MyPackage.SubPackage.ClassA()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassA(SubPackage.ClassB):
    thingA: 'SubPackage.ClassA'
    thingB: SubPackage.ClassB

    def __init__(self):
        self.thingA = None
        self.thingB = None

    def test(self):
        self.thingA = SubPackage.ClassA()
        self.thingB = SubPackage.ClassB()
from __future__ import absolute_import
from MyPackage import SubPackage


class ClassB(object):
    nextB: 'SubPackage.ClassB'

    def __init__(self):
        self.nextB= None

    def test(self):
        self.nextB= SubPackage.ClassB()

import语句也相当于
from。。如果需要,使用相对导入而不是绝对导入导入子包
。在风格上,我倾向于使用相对导入来帮助我快速确定哪些导入是我项目的一部分,哪些是外部依赖项。

为什么需要完全限定所有内容?为什么有这么多模块?如果问题中的代码具有代表性,则说明您的模块非常短。通常在每个模块中只包含几个类,这样就不需要导入这么多。有理由不这样做吗?此外,除非有名称冲突,否则最好使用较短的引用。可能有100个模块,最多约5个子包。子包中的类可能相互关联(派生自另一个子包中的类)并使用其他子包中的类。因此存在名称冲突的可能性,因此完全限定名称将更可取。将
MyPackage
从名称链中删除应该使变量具有足够的限定性,以避免冲突,并消除引用问题(我认为是鸡和蛋)。在“文件A”和B中,只需从MyPackage导入子模块中导入
,然后在名称中跳过
MyPackage.
。FTR调用这些长属性链可能会对性能产生明显影响(attr调用并不快)。@Sprotty听起来,将模块整合为更少的模块会让您受益匪浅。特别是当类相互依赖时,将它们包含在同一个模块中要简单得多。模块和包不用于创建详细的分类法。它们用于提供大型的函数、类和变量分组,以便协同工作或避免名称冲突。如果您在一个包中有数百个模块,那么您可能正在做一些非Pythonic的事情。在顶级包中,考虑别名而不是完全限定。源数据(这些类将从中生成)被分解成若干个“命名空间”,因此在2个命名空间中可能出现相同的名称。我认为对于每个名称空间,子包都是一个很好的容器。如果每个命名空间中的类是独立的,那么每个子包可以是单个模块,但是每个子包中的类之间可能存在相互关系,即nsA:cls1派生自nsB:cls2,后者派生自nsA:cls3。保证它们按正确顺序定义的一种方法是拆分1个类/模块,除非Python可以进行前向声明?奇怪的是,即使添加了第二个子包,这似乎也能起作用。我不得不说,我并不真正理解最初的错误,但这看起来是一个可行的解决方案。@Sprotty我不认为包是为了在顶级导入它们自己。。您必须至少降低一个级别(即:子包级别)。提升级别的唯一原因是导入一个完全独立的包。