Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python如何拥有一个可以执行和导入的模块_Python_Oop - Fatal编程技术网

Python如何拥有一个可以执行和导入的模块

Python如何拥有一个可以执行和导入的模块,python,oop,Python,Oop,我有一个Python包mypackage,其中包含一组具有以下目录结构的模块/类: ├── interface.py ├── mypackage/ | └── __init__.py | └── classA.py | └── classB.py | └── ... 当前用例是将interface.py与一组argparse标志一起使用: python interface.py --foo --bar 在interface.py内部,它用mypackage实例化一组类,并运

我有一个Python包
mypackage
,其中包含一组具有以下目录结构的模块/类:

├── interface.py
├── mypackage/
|   └── __init__.py
|   └── classA.py
|   └── classB.py
|   └── ...
当前用例是将
interface.py
与一组
argparse
标志一起使用:

python interface.py --foo --bar 
interface.py
内部,它用
mypackage
实例化一组类,并运行它们的方法。比如:

from classA import ClassA

def interfaceMethod(foo, bar):
    a = ClassA(foo, ...)
    print(a.classMethod(bar, ...)

if args.foo: interfaceMethod(args.foo, args.bar)
import mypackage
print(mypackage.interfaceMethod(foo, bar)
这在让非python/程序员使用我的代码时效果很好。但是我也希望能够在Python代码中导入我的包,并在
interface.py
中运行相同的方法。比如:

from classA import ClassA

def interfaceMethod(foo, bar):
    a = ClassA(foo, ...)
    print(a.classMethod(bar, ...)

if args.foo: interfaceMethod(args.foo, args.bar)
import mypackage
print(mypackage.interfaceMethod(foo, bar)
问题

  • 是否有标准/最佳的方法来实现这一点
  • 注意:我认为用户不需要查看我的类结构,因此我希望有一个面向用户的类来实现
    interface.py中的所有方法
解决方案1(我认为这不是首选方案):

interface.py
中的方法添加到
\uuuu init\uuuu.py
中:

# in __init__.py
from classA import ClassA

def interfaceMethod():
    a = ClassA(foo)
    print(a.classMethod(bar))
setup(
    # other arguments here...
    entry_points={
        'console_scripts': [
            'script_name = my_package.interface:interfaceMethod',
        ],
    }
)
然后用户可以在自己的代码中执行以下操作(在
interface.py中看起来也非常类似):

解决方案2:

创建一个
mypackage
类:

class MyPackage():
    self.classA = ClassA(...)
    self.classB = ClassB(...)

    def interfaceMethod():
        a = self.classA()

如果我创建这个类,我应该担心包和类具有相同的名称吗?我是否更改包结构的层次结构以反映
MyPackage
是前向类

使用
setup.py
并使用

将您的
interface.py
放入软件包中,并将其放入您的
setup.py

# in __init__.py
from classA import ClassA

def interfaceMethod():
    a = ClassA(foo)
    print(a.classMethod(bar))
setup(
    # other arguments here...
    entry_points={
        'console_scripts': [
            'script_name = my_package.interface:interfaceMethod',
        ],
    }
)
接口.py更改为:

from classA import ClassA

def interfaceMethod(foo, bar):
    a = ClassA(foo, ...)
    print(a.classMethod(bar, ...)

if __name__ == '__main__':
    interfaceMethod(args.foo, args.bar)
使用
Python setup.py install
安装后,可以调用您的程序 从命令行:

script_name --foo --bar 
有关详细信息,请参阅

您仍然可以通过以下方式导入它:

from mypackage import interface
interface.interfaceMethod()

最终的问题是:我如何拥有一个可以执行和导入的模块?我不喜欢将代码添加到个人偏好的
\uuuu init\uuuuuuuuuy.py
。这会使我们很难弄清楚哪些事情是由于转发的进口造成的。如果您正在开发一个其他python开发人员为了缩短名称而使用的API,那就太好了。除此之外,我建议避免使用。当初学者导入mypackage时,它会抛出一个循环;mypackage.doStuff()
,实际上,
doStuff()
在目录层次结构中有700层,而不是预期的第一层。他们最终会来找你,因为他们无法找出模块在文件系统上的实际位置。我不确定这是否只是你在这里给出的抽象伪代码示例的一部分,但我想确保你理解Python模块和类不需要密切相关。与Java不同,每个类不需要单独的文件,每个模块也不需要单独的类。在需要单独全局命名空间的任何位置使用单独的模块。在希望将数据与方法关联的任何位置使用类。“不要混淆这两个概念。”马修斯说,“当然,我认为这比我现在的问题更有意义。更改了标题,谢谢。@Blckknght我试图使我的伪代码尽可能简单,但我有理由将我的类拆分为不同的文件。这与我已经做的非常相似:
设置(scripts='myinterface.py',…)
。界面脚本有几十种方法,因此我不想在
console\u scripts
下列出每种方法。使用or或生成不同的方法子命令如何?