如何打包导入在Python中产生副作用的库?

时间:2017-09-03 14:42:11

标签: python python-import packaging setup.py pypi

我正在开发一个python库(不是我的),看起来像这样:

.
├── README.md
├── setup.py
└── library
    ├── __init__.py
    ├── core.py
    ├── a.py
    └── b.py

文件__init__.py使用core.pya.py本身使用b.pyimport library。需要注意的重要一点是core.py有一些有意识的意图。

但是,我想让用户可以使用import library.core的功能而不会产生任何副作用。不幸的是,正如您所知,from library import core__init__.py无论如何都会执行setup.py(发生副作用)。

您知道我如何重新组织我的包和. ├── README.md ├── setup.py ├── library_core │ ├── __init__.py │ ├── core.py │ ├── a.py │ └── b.py └── library └── __init__.py # Import library_core and apply side effects 以解决此问题?

我想到了这样的事情:

setup.py

我会使用packages = ['library', 'library_core']更新library。这样,导入library_core不会更改任何内容,但用户可以导入library_core而不会产生任何副作用。此外,这将避免重复代码,一切都将保留在同一个存储库中。

不幸的是,这不起作用,因为我无法从library导入=COUNTA(FILTER(A14:O,SEARCH($A$4,A14:A),SEARCH("*",F14:F)))/2 ,因为它们不在文件树中的相同位置。

2 个答案:

答案 0 :(得分:0)

我建议您停止依赖副作用,并要求用户通过调用记录的函数显式触发它们。否则你正在打一场失败的战斗:默认目前是触发副作用,然后你必须撤消它们,如果用户不想要它们。

答案 1 :(得分:0)

使用两个包似乎是最好的方法。

只有安装了整个库(例如python setup.py install),两个相邻软件包的使用才能。这使得开发变得相当复杂,例如对于单元测试:由于import library无法进行,因为如果没有安装library_core,则无法找到它。

因此,最好的解决方案是简单地创建一个子包,并在setup.py library_core中指定package_dir所在的. ├── README.md ├── setup.py └── library ├── __init__.py └── core ├── __init__.py ├── a.py └── b.py 选项。

文件树看起来像这样:

setup.py

setup( name = 'library', packages = ['library', 'library.core', 'library_core'], package_dir = {'library_core': 'library/core'}, ... )

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <cstdio>
#include <cstdlib>

// replacement of a minimal set of functions:
void *operator new(std::size_t sz)
{
    void *ptr = std::malloc(sz);
    std::printf("global op new called, size = %zu, pointer = 0x%p\n", sz, ptr);
    return ptr;
}

void operator delete(void* ptr) noexcept
{
    std::printf("global op delete called, pointer = 0x%p\n", ptr);
    std::free(ptr);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}