标签归档:module

什么是。在Python中的import语句中是什么意思?

问题:什么是。在Python中的import语句中是什么意思?

我正在查看Python multiprocessing模块的代码,其中包含以下行:

from ._multiprocessing import win32, Connection, PipeConnection

代替

from _multiprocessing import win32, Connection, PipeConnection

细微的差别是前一个时期_multiprocessing。那是什么意思?为什么要月经?

I’m looking over the code for Python’s multiprocessing module, and it contains this line:

from ._multiprocessing import win32, Connection, PipeConnection

instead of

from _multiprocessing import win32, Connection, PipeConnection

the subtle difference being the period before _multiprocessing. What does that mean? Why the period?


回答 0

这是显式相对导入的新语法。这意味着从当前包导入。

That’s the new syntax for explicit relative imports. It means import from the current package.


回答 1

模块名称中的点用于相对模块导入(请参见此处此处,第6.4.2节)。

您可以使用多个点,而不是指当前软件包,而是指其父对象。这仅应在包内使用,在主模块中,应始终使用绝对模块名称。

The dot in the module name is used for relative module import (see here and here, section 6.4.2).

You can use more than one dot, referring not to the curent package but its parent(s). This should only be used within packages, in the main module one should always use absolute module names.


您可以在Python中为导入的模块定义别名吗?

问题:您可以在Python中为导入的模块定义别名吗?

在Python中,是否可以为导入的模块定义别名?

例如:

import a_ridiculously_long_module_name

…因此具有别名“ short_name”。

In Python, is it possible to define an alias for an imported module?

For instance:

import a_ridiculously_long_module_name

…so that is has an alias of ‘short_name’.


回答 0

import a_ridiculously_long_module_name as short_name

也适用于

import module.submodule.subsubmodule as short_name
import a_ridiculously_long_module_name as short_name

also works for

import module.submodule.subsubmodule as short_name

回答 1

在这里检查

import module as name

要么

from relative_module import identifier as name

Check here

import module as name

or

from relative_module import identifier as name

回答 2

如果已经完成:

import long_module_name

您还可以通过以下方式为其命名:

lmn = long_module_name

没有理由在代码中以这种方式执行此操作,但有时我发现它在交互式解释器中很有用。

If you’ve done:

import long_module_name

you can also give it an alias by:

lmn = long_module_name

There’s no reason to do it this way in code, but I sometimes find it useful in the interactive interpreter.


回答 3

是的,可以使用别名导入模块。使用作为关键字。看到

import math as ilovemaths # here math module is imported under an alias name
print(ilovemaths.sqrt(4))  # Using the sqrt() function

Yes, modules can be imported under an alias name. using as keyword. See

import math as ilovemaths # here math module is imported under an alias name
print(ilovemaths.sqrt(4))  # Using the sqrt() function

回答 4

从MODULE导入TAGNAME作为ALIAS

from MODULE import TAGNAME as ALIAS


如何在当前模块上调用setattr()?

问题:如何在当前模块上调用setattr()?

如何将第一个参数“ object”传递给函数setattr(object, name, value),以在当前模块上设置变量?

例如:

setattr(object, "SOME_CONSTANT", 42);

具有与以下相同的效果:

SOME_CONSTANT = 42

在包含这些行的模块中(带有正确的object)。

我在模块级别动态生成几个值,由于无法__getattr__在模块级别定义,所以这是我的后备。

What do I pass as the first parameter “object” to the function setattr(object, name, value), to set variables on the current module?

For example:

setattr(object, "SOME_CONSTANT", 42);

giving the same effect as:

SOME_CONSTANT = 42

within the module containing these lines (with the correct object).

I’m generate several values at the module level dynamically, and as I can’t define __getattr__ at the module level, this is my fallback.


回答 0

import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

或者,不使用setattr(打破问题的字母,但满足相同的实际目的;-):

globals()[name] = value

注意:在模块范围内,后者等效于:

vars()[name] = value

这更加简洁,但是在函数内部不起作用(vars()给出在其范围内调用的变量:在全局范围内调用时模块的变量,然后可以使用R / W,但在函数中可以使用变量在函数中调用时,然后必须将其视为R / O - Python在线文档对此特定区别可能会造成混淆。

import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

or, without using setattr (which breaks the letter of the question but satisfies the same practical purposes;-):

globals()[name] = value

Note: at module scope, the latter is equivalent to:

vars()[name] = value

which is a bit more concise, but doesn’t work from within a function (vars() gives the variables of the scope it’s called at: the module’s variables when called at global scope, and then it’s OK to use it R/W, but the function’s variables when called in a function, and then it must be treated as R/O — the Python online docs can be a bit confusing about this specific distinction).


回答 1

如果必须从模块内部设置模块范围的变量,那有什么问题global呢?

# my_module.py

def define_module_scoped_variables():
    global a, b, c
    a, b, c = 'a', ['b'], 3

从而:

>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']

If you must set module scoped variables from within the module, what’s wrong with global?

# my_module.py

def define_module_scoped_variables():
    global a, b, c
    a, b, c = 'a', ['b'], 3

thus:

>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']

回答 2

在Python 3.7中,您将可以__getattr__在模块级别使用(相关答案)。

根据PEP 562

def __getattr__(name):
    if name == "SOME_CONSTANT":
        return 42
    raise AttributeError(f"module {__name__} has no attribute {name}")

In Python 3.7, you will be able to use __getattr__ at the module level (related answer).

Per PEP 562:

def __getattr__(name):
    if name == "SOME_CONSTANT":
        return 42
    raise AttributeError(f"module {__name__} has no attribute {name}")

回答 3

  1. 你不会的 你会做globals()["SOME_CONSTANT"] = 42
  2. 你不会的 您会将动态生成的内容存储在模块以外的其他位置。
  1. You wouldn’t. You would do globals()["SOME_CONSTANT"] = 42
  2. You wouldn’t. You would store dynamically-generated content somewhere other than a module.

如何导入上面目录中的Python类?

问题:如何导入上面目录中的Python类?

我想从当前目录上方目录中的文件中的类继承。

是否可以相对导入该文件?

I want to inherit from a class in a file that lies in a directory above the current one.

Is it possible to relatively import that file?


回答 0

from ..subpkg2 import mod

根据Python文档:在包层次结构中,请使用两个点,如import语句 doc所述:

指定要导入的模块时,不必指定模块的绝对名称。当一个模块或程序包包含在另一个程序包中时,可以在同一顶部程序包中进行相对导入,而不必提及程序包名称。之后,通过在指定的模块或程序包中使用前导点,from可以指定在不指定确切名称的情况下遍历当前程序包层次结构的高度。一个前导点表示进行导入的模块所在的当前包。两点表示一个包装级别。三个点在两个级别上,依此类推。因此,如果from . import modpkg包中的模块执行,则最终将导入pkg.mod。如果from ..subpkg2 import mod从内部执行,pkg.subpkg1则将导入pkg.subpkg2.mod。相对进口的规范包含在PEP 328中

PEP 328处理绝对/相对进口。

from ..subpkg2 import mod

Per the Python docs: When inside a package hierarchy, use two dots, as the import statement doc says:

When specifying what module to import you do not have to specify the absolute name of the module. When a module or package is contained within another package it is possible to make a relative import within the same top package without having to mention the package name. By using leading dots in the specified module or package after from you can specify how high to traverse up the current package hierarchy without specifying exact names. One leading dot means the current package where the module making the import exists. Two dots means up one package level. Three dots is up two levels, etc. So if you execute from . import mod from a module in the pkg package then you will end up importing pkg.mod. If you execute from ..subpkg2 import mod from within pkg.subpkg1 you will import pkg.subpkg2.mod. The specification for relative imports is contained within PEP 328.

PEP 328 deals with absolute/relative imports.


回答 1

import sys
sys.path.append("..") # Adds higher directory to python modules path.
import sys
sys.path.append("..") # Adds higher directory to python modules path.

回答 2

如果您可以保证他提到的软件包层次结构, @gimel的答案是正确的。如果您不能-如果您的真正需要如您所表达的那样,完全与目录绑定,并且与打包没有任何必要的关系-那么您需要__file__继续寻找父目录(几个os.path.dirname调用即可; – ),然后(如果该目录尚未上sys.path)预先准备暂时插入说,在非常的启动目录sys.path__import__,除去上述再DIR -事实上杂乱的工作,但是,“当你必须,你必须”(和Pyhon努力永不停止程序员做必须做的事情做的事情-就像ISO C标准在其序言中“ C的精神”部分中所说!!)。

这是一个可能适合您的示例:

import sys
import os.path
sys.path.append(
    os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))

import module_in_parent_dir

@gimel’s answer is correct if you can guarantee the package hierarchy he mentions. If you can’t — if your real need is as you expressed it, exclusively tied to directories and without any necessary relationship to packaging — then you need to work on __file__ to find out the parent directory (a couple of os.path.dirname calls will do;-), then (if that directory is not already on sys.path) prepend temporarily insert said dir at the very start of sys.path, __import__, remove said dir again — messy work indeed, but, “when you must, you must” (and Pyhon strives to never stop the programmer from doing what must be done — just like the ISO C standard says in the “Spirit of C” section in its preface!-).

Here is an example that may work for you:

import sys
import os.path
sys.path.append(
    os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir)))

import module_in_parent_dir

回答 3

从当前目录正上方一层的目录中导入模块:

from .. import module

Import module from a directory which is exactly one level above the current directory:

from .. import module

回答 4

如何加载目录中的模块

前言:我对以前的答案进行了实质性的重写,希望能够帮助人们轻松地进入python的生态系统,并希望通过python的导入系统为每个人带来最大的成功改变。

这将涵盖软件包中的相对进口,我认为这是OP问题最可能的情况。

Python是一个模块化系统

这就是为什么我们编写import foo从根命名空间加载模块“ foo”而不是编写的原因:

foo = dict();  # please avoid doing this
with open(os.path.join(os.path.dirname(__file__), '../foo.py') as foo_fh:  # please avoid doing this
    exec(compile(foo_fh.read(), 'foo.py', 'exec'), foo)  # please avoid doing this

Python未与文件系统耦合

这就是为什么我们可以在没有实际文件系统的环境中嵌入python而无需提供虚拟文件系统(例如Jython)的原因。

与文件系统脱钩,可以灵活地进行导入,该设计允许从存档/ zip文件导入,导入单例,字节码缓存,cffi扩展,甚至远程代码定义加载。

因此,如果导入未与文件系统耦合,“向上目录”是什么意思?我们挑选出一些启发,但一中工作时,我们能做到这一点,例如包装,一些启发式已经被定义,使得像相对进口.foo..foo在同一封装内的工作。凉!

如果您真诚地希望将源代码加载模式耦合到文件系统,则可以这样做。您必须选择自己的试探法,并使用某种导入机制,我建议使用importlib

Python的importlib示例如下所示:

import importlib.util
import sys

# For illustrative purposes.
file_path = os.path.join(os.path.dirname(__file__), '../foo.py')
module_name = 'foo'

foo_spec = importlib.util.spec_from_file_location(module_name, file_path)
# foo_spec is a ModuleSpec specifying a SourceFileLoader
foo_module = importlib.util.module_from_spec(foo_spec)
sys.modules[module_name] = foo_module
foo_spec.loader.exec_module(foo_module)

foo = sys.modules[module_name]
# foo is the sys.modules['foo'] singleton

打包

这里有一个很好的官方示例项目:https//github.com/pypa/sampleproject

python软件包是有关您的源代码的信息的集合,该软件包可以告知其他工具如何将您的源代码复制到其他计算机,以及如何将源代码集成到该系统的路径中,从而import foo适用于其他计算机(无论解释器,主机操作系统等)

目录结构

让我们foo在某个目录(最好是空目录)中有一个包名。

some_directory/
    foo.py  # `if __name__ == "__main__":`  lives here

我的首选是创建setup.py与的兄弟姐妹foo.py,因为它使setup.py文件的编写更加简单,但是您可以编写配置来更改/重定向setuptools默认情况下愿意做的一切;例如放在foo.py“ src /”目录下比较流行,这里不做介绍。

some_directory/
    foo.py
    setup.py

#!/usr/bin/env python3
# setup.py

import setuptools

setuptools.setup(
    name="foo",
    ...
    py_modules=['foo'],
)

python3 -m pip install --editable ./  # or path/to/some_directory/

“可编辑” -e又将再次重定向导入机制,以将源文件加载到此目录中,而不是将当前的确切文件复制到安装环境的库中。这也可能导致开发人员机器上的行为差异,请务必测试您的代码!除了pip之外,还有其他工具,但是我建议您将pip用作入门工具:)

我还想制作foo一个“包”(包含的目录__init__.py)而不是一个模块(一个“ .py”文件),“包”和“模块”都可以加载到根命名空间中,模块允许嵌套命名空间,如果我们要进行“相对一个目录向上”导入,这将很有帮助。

some_directory/
    foo/
        __init__.py
    setup.py

#!/usr/bin/env python3
# setup.py

import setuptools

setuptools.setup(
    name="foo",
    ...
    packages=['foo'],
)

我也喜欢做一个foo/__main__.py,这允许python将包作为模块python3 -m foo执行,例如将foo/__main__.py作为__main__

some_directory/
    foo/
        __init__.py
        __main__.py  # `if __name__ == "__main__":`  lives here, `def main():` too!
    setup.py

#!/usr/bin/env python3
# setup.py

import setuptools

setuptools.setup(
    name="foo",
    ...
    packages=['foo'],
    ...
    entry_points={
        'console_scripts': [
            # "foo" will be added to the installing-environment's text mode shell, eg `bash -c foo`
            'foo=foo.__main__:main',
        ]
    },
)

让我们用更多的模块充实一下:基本上,您可以拥有一个目录结构,如下所示:

some_directory/
    bar.py           # `import bar`
    foo/
        __init__.py  # `import foo`
        __main__.py
        baz.py       # `import foo.baz
        spam/           
            __init__.py  # `import foo.spam`
            eggs.py      # `import foo.spam.eggs`
    setup.py

setup.py 按照惯例,其中包含有关源代码的元数据信息,例如:

  • 安装名为“ install_requires”所需的依赖项
  • 软件包管理应使用什么名称(安装/卸载“名称”),在我们的案例中,建议与主python软件包名称匹配 foo,,尽管用下划线代替连字符很普遍
  • 许可信息
  • 成熟度标签(alpha / beta / etc),
  • 受众标签(用于开发人员,用于机器学习等),
  • 单页文档内容(如自述文件),
  • 外壳程序名称(您在用户外壳程序上键入的名称(如bash)或在图形用户外壳程序中找到的名称(如开始菜单)),
  • 该软件包将安装(和卸载)的python模块列表
  • 实际的“运行测试”入口点 python ./setup.py test

它非常广泛,如果在开发机器上安装了源模块,它甚至可以即时编译c扩展。对于每天的示例,我建议使用PYPA样本存储库的setup.py

如果要发布构建工件(例如,旨在运行几乎相同的计算机的代码副本),则requests.txt文件是用于快照确切的依赖项信息的一种流行方法,其中“ install_requires”是捕获最小数量和最小数量的好方法。最高兼容版本。但是,无论如何目标计算机几乎都是相同的,我强烈建议创建一个完整的python前缀的tarball。这可能很棘手,太详细了,无法在此处介绍。签出pip install--target签选项,或virtualenv aka venv寻找线索。

回到例子

如何在一个目录下导入文件:

在foo / spam / eggs.py中,如果需要foo / baz中的代码,我们可以通过其绝对命名空间来请求它:

import foo.baz

如果我们想保留将来通过其他一些相对baz实现将eggs.py移到其他目录的功能,可以使用相对导入,例如:

import ..baz

How to load a module that is a directory up

preface: I did a substantial rewrite of a previous answer with the hopes of helping ease people into python’s ecosystem, and hopefully give everyone the best change of success with python’s import system.

This will cover relative imports within a package, which I think is the most probable case to OP’s question.

Python is a modular system

This is why we write import foo to load a module “foo” from the root namespace, instead of writing:

foo = dict();  # please avoid doing this
with open(os.path.join(os.path.dirname(__file__), '../foo.py') as foo_fh:  # please avoid doing this
    exec(compile(foo_fh.read(), 'foo.py', 'exec'), foo)  # please avoid doing this

Python isn’t coupled to a file-system

This is why we can embed python in environment where there isn’t a defacto filesystem without providing a virtual one, such as Jython.

Being decoupled from a filesystem lets imports be flexible, this design allows for things like imports from archive/zip files, import singletons, bytecode caching, cffi extensions, even remote code definition loading.

So if imports are not coupled to a filesystem what does “one directory up” mean? We have to pick out some heuristics but we can do that, for example when working within a package, some heuristics have already been defined that makes relative imports like .foo and ..foo work within the same package. Cool!

If you sincerely want to couple your source code loading patterns to a filesystem, you can do that. You’ll have to choose your own heuristics, and use some kind of importing machinery, I recommend importlib

Python’s importlib example looks something like so:

import importlib.util
import sys

# For illustrative purposes.
file_path = os.path.join(os.path.dirname(__file__), '../foo.py')
module_name = 'foo'

foo_spec = importlib.util.spec_from_file_location(module_name, file_path)
# foo_spec is a ModuleSpec specifying a SourceFileLoader
foo_module = importlib.util.module_from_spec(foo_spec)
sys.modules[module_name] = foo_module
foo_spec.loader.exec_module(foo_module)

foo = sys.modules[module_name]
# foo is the sys.modules['foo'] singleton

Packaging

There is a great example project available officially here: https://github.com/pypa/sampleproject

A python package is a collection of information about your source code, that can inform other tools how to copy your source code to other computers, and how to integrate your source code into that system’s path so that import foo works for other computers (regardless of interpreter, host operating system, etc)

Directory Structure

Lets have a package name foo, in some directory (preferably an empty directory).

some_directory/
    foo.py  # `if __name__ == "__main__":`  lives here

My preference is to create setup.py as sibling to foo.py, because it makes writing the setup.py file simpler, however you can write configuration to change/redirect everything setuptools does by default if you like; for example putting foo.py under a “src/” directory is somewhat popular, not covered here.

some_directory/
    foo.py
    setup.py

.

#!/usr/bin/env python3
# setup.py

import setuptools

setuptools.setup(
    name="foo",
    ...
    py_modules=['foo'],
)

.

python3 -m pip install --editable ./  # or path/to/some_directory/

“editable” aka -e will yet-again redirect the importing machinery to load the source files in this directory, instead copying the current exact files to the installing-environment’s library. This can also cause behavioral differences on a developer’s machine, be sure to test your code! There are tools other than pip, however I’d recommend pip be the introductory one :)

I also like to make foo a “package” (a directory containing __init__.py) instead of a module (a single “.py” file), both “packages” and “modules” can be loaded into the root namespace, modules allow for nested namespaces, which is helpful if we want to have a “relative one directory up” import.

some_directory/
    foo/
        __init__.py
    setup.py

.

#!/usr/bin/env python3
# setup.py

import setuptools

setuptools.setup(
    name="foo",
    ...
    packages=['foo'],
)

I also like to make a foo/__main__.py, this allows python to execute the package as a module, eg python3 -m foo will execute foo/__main__.py as __main__.

some_directory/
    foo/
        __init__.py
        __main__.py  # `if __name__ == "__main__":`  lives here, `def main():` too!
    setup.py

.

#!/usr/bin/env python3
# setup.py

import setuptools

setuptools.setup(
    name="foo",
    ...
    packages=['foo'],
    ...
    entry_points={
        'console_scripts': [
            # "foo" will be added to the installing-environment's text mode shell, eg `bash -c foo`
            'foo=foo.__main__:main',
        ]
    },
)

Lets flesh this out with some more modules: Basically, you can have a directory structure like so:

some_directory/
    bar.py           # `import bar`
    foo/
        __init__.py  # `import foo`
        __main__.py
        baz.py       # `import foo.baz
        spam/           
            __init__.py  # `import foo.spam`
            eggs.py      # `import foo.spam.eggs`
    setup.py

setup.py conventionally holds metadata information about the source code within, such as:

  • what dependencies are needed to install named “install_requires”
  • what name should be used for package management (install/uninstall “name”), I suggest this match your primary python package name in our case foo, though substituting underscores for hyphens is popular
  • licensing information
  • maturity tags (alpha/beta/etc),
  • audience tags (for developers, for machine learning, etc),
  • single-page documentation content (like a README),
  • shell names (names you type at user shell like bash, or names you find in a graphical user shell like a start menu),
  • a list of python modules this package will install (and uninstall)
  • a defacto “run tests” entry point python ./setup.py test

Its very expansive, it can even compile c extensions on the fly if a source module is being installed on a development machine. For a every-day example I recommend the PYPA Sample Repository’s setup.py

If you are releasing a build artifact, eg a copy of the code that is meant to run nearly identical computers, a requirements.txt file is a popular way to snapshot exact dependency information, where “install_requires” is a good way to capture minimum and maximum compatible versions. However, given that the target machines are nearly identical anyway, I highly recommend creating a tarball of an entire python prefix. This can be tricky, too detailed to get into here. Check out pip install‘s --target option, or virtualenv aka venv for leads.

back to the example

how to import a file one directory up:

From foo/spam/eggs.py, if we wanted code from foo/baz we could ask for it by its absolute namespace:

import foo.baz

If we wanted to reserve capability to move eggs.py into some other directory in the future with some other relative baz implementation, we could use a relative import like:

import ..baz

回答 5

Python是一个模块化系统

Python不依赖文件系统

为了可靠地加载python代码,请将该代码放在模块中,然后将该模块安装在python的库中。

已安装的模块始终可以通过以下方式从顶级命名空间加载: import <name>


这里有一个很好的示例项目正式可用:https : //github.com/pypa/sampleproject

基本上,您可以具有如下目录结构:

the_foo_project/
    setup.py  

    bar.py           # `import bar`
    foo/
      __init__.py    # `import foo`

      baz.py         # `import foo.baz`

      faz/           # `import foo.faz`
        __init__.py
        daz.py       # `import foo.faz.daz` ... etc.

一定要声明你setuptools.setup()setup.py

官方示例:https//github.com/pypa/sampleproject/blob/master/setup.py

在我们的例子中,我们可能想导出bar.pyfoo/__init__.py我的简短示例:

setup.py

#!/usr/bin/env python3

import setuptools

setuptools.setup(
    ...
    py_modules=['bar'],
    packages=['foo'],
    ...
    entry_points={}, 
        # Note, any changes to your setup.py, like adding to `packages`, or
        # changing `entry_points` will require the module to be reinstalled;
        # `python3 -m pip install --upgrade --editable ./the_foo_project
)

现在我们可以将模块安装到python库中;使用pip,您可以the_foo_project在编辑模式下安装到python库中,因此我们可以实时对其进行处理

python3 -m pip install --editable=./the_foo_project

# if you get a permission error, you can always use 
# `pip ... --user` to install in your user python library

现在,从任何python上下文中,我们都可以加载共享的py_modules和包

foo_script.py

#!/usr/bin/env python3

import bar
import foo

print(dir(bar))
print(dir(foo))

Python is a modular system

Python doesn’t rely on a file system

To load python code reliably, have that code in a module, and that module installed in python’s library.

Installed modules can always be loaded from the top level namespace with import <name>


There is a great sample project available officially here: https://github.com/pypa/sampleproject

Basically, you can have a directory structure like so:

the_foo_project/
    setup.py  

    bar.py           # `import bar`
    foo/
      __init__.py    # `import foo`

      baz.py         # `import foo.baz`

      faz/           # `import foo.faz`
        __init__.py
        daz.py       # `import foo.faz.daz` ... etc.

.

Be sure to declare your setuptools.setup() in setup.py,

official example: https://github.com/pypa/sampleproject/blob/master/setup.py

In our case we probably want to export bar.py and foo/__init__.py, my brief example:

setup.py

#!/usr/bin/env python3

import setuptools

setuptools.setup(
    ...
    py_modules=['bar'],
    packages=['foo'],
    ...
    entry_points={}, 
        # Note, any changes to your setup.py, like adding to `packages`, or
        # changing `entry_points` will require the module to be reinstalled;
        # `python3 -m pip install --upgrade --editable ./the_foo_project
)

.

Now we can install our module into the python library; with pip, you can install the_foo_project into your python library in edit mode, so we can work on it in real time

python3 -m pip install --editable=./the_foo_project

# if you get a permission error, you can always use 
# `pip ... --user` to install in your user python library

.

Now from any python context, we can load our shared py_modules and packages

foo_script.py

#!/usr/bin/env python3

import bar
import foo

print(dir(bar))
print(dir(foo))

ModuleNotFoundError:__main__不是软件包是什么意思?

问题:ModuleNotFoundError:__main__不是软件包是什么意思?

我正在尝试从控制台运行模块。我的目录结构是这样的:

我正在尝试使用以下命令p_03_using_bisection_search.pyproblem_set_02目录中运行模块:

$ python3 p_03_using_bisection_search.py

里面的代码p_03_using_bisection_search.py是:

__author__ = 'm'


from .p_02_paying_debt_off_in_a_year import compute_balance_after


def compute_bounds(balance: float,
                   annual_interest_rate: float) -> (float, float):

    # there is code here, but I have omitted it to save space
    pass


def compute_lowest_payment(balance: float,
                           annual_interest_rate: float) -> float:

    # there is code here, but I have omitted it to save space
    pass    

def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(input('Enter the annual interest rate: '))

    lowest_payment = compute_lowest_payment(balance, annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

我正在导入p_02_paying_debt_off_in_a_year.py其中代码是的函数:

__author__ = 'm'


def compute_balance(balance: float,
                    fixed_payment: float,
                    annual_interest_rate: float) -> float:

    # this is code that has been omitted
    pass


def compute_balance_after(balance: float,
                          fixed_payment: float,
                          annual_interest_rate: float,
                          months: int=12) -> float:

    # Omitted code
    pass


def compute_fixed_monthly_payment(balance: float,
                                  annual_interest_rate: float) -> float:

    # omitted code
    pass


def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(
        input('Enter the annual interest rate as a decimal: '))
    lowest_payment = compute_fixed_monthly_payment(balance,
                                                   annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

我收到以下错误:

ModuleNotFoundError: No module named '__main__.p_02_paying_debt_off_in_a_year'; '__main__' is not a package

我不知道如何解决这个问题。我尝试添加__init__.py文件,但是仍然无法正常工作。

I am trying to run a module from the console. The structure of my directory is this:

I am trying to run the module p_03_using_bisection_search.py, from the problem_set_02 directory using:

$ python3 p_03_using_bisection_search.py

The code inside p_03_using_bisection_search.pyis:

__author__ = 'm'


from .p_02_paying_debt_off_in_a_year import compute_balance_after


def compute_bounds(balance: float,
                   annual_interest_rate: float) -> (float, float):

    # there is code here, but I have omitted it to save space
    pass


def compute_lowest_payment(balance: float,
                           annual_interest_rate: float) -> float:

    # there is code here, but I have omitted it to save space
    pass    

def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(input('Enter the annual interest rate: '))

    lowest_payment = compute_lowest_payment(balance, annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

I am importing a function that is in p_02_paying_debt_off_in_a_year.py which code is:

__author__ = 'm'


def compute_balance(balance: float,
                    fixed_payment: float,
                    annual_interest_rate: float) -> float:

    # this is code that has been omitted
    pass


def compute_balance_after(balance: float,
                          fixed_payment: float,
                          annual_interest_rate: float,
                          months: int=12) -> float:

    # Omitted code
    pass


def compute_fixed_monthly_payment(balance: float,
                                  annual_interest_rate: float) -> float:

    # omitted code
    pass


def main():
    balance = eval(input('Enter the initial balance: '))
    annual_interest_rate = eval(
        input('Enter the annual interest rate as a decimal: '))
    lowest_payment = compute_fixed_monthly_payment(balance,
                                                   annual_interest_rate)
    print('Lowest Payment: ' + str(lowest_payment))


if __name__ == '__main__':
    main()

I am getting the following error:

ModuleNotFoundError: No module named '__main__.p_02_paying_debt_off_in_a_year'; '__main__' is not a package

I have no idea how to solve this issue. I have tried adding a __init__.py file, but it is still not working.


回答 0

只需删除相对导入的点,然后执行以下操作:

from p_02_paying_debt_off_in_a_year import compute_balance_after

Simply remove the dot for the relative import and do:

from p_02_paying_debt_off_in_a_year import compute_balance_after

回答 1

我和你有同样的问题。我认为问题是您在中使用了相对导入in-package import__init__.py您的目录中没有。因此,请按照以上摩西的回答进行导入。

我认为核心问题是在导入点时:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

它等效于:

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

where __main__指您当前的模块p_03_using_bisection_search.py


简而言之,解释器不知道您的目录体系结构。

当解释器进入时p_03.py,脚本等于:

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

并且p_03_using_bisection_search不包含任何名为的模块或实例p_02_paying_debt_off_in_a_year


因此,我想出了一个更干净的解决方案,而无需更改python环境的贵重物品(在查找请求在相对导入中的作用之后):

该目录的主要体系结构是:

main.py

setup.py

problem_set_02/

——__init__.py

——p01.py

——p02.py

——p03.py

然后写__init__.py

from .p_02_paying_debt_off_in_a_year import compute_balance_after

这里__main____init__,它究竟指的是模块problem_set_02

然后转到main.py

import problem_set_02

您也可以编写一个setup.py将特定模块添加到环境中。

I have the same issue as you did. I think the problem is that you used relative import in in-package import. There is no __init__.py in your directory. So just import as Moses answered above.

The core issue I think is when you import with a dot:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

It is equivalent to:

from __main__.p_02_paying_debt_off_in_a_year import compute_balance_after

where __main__ refers to your current module p_03_using_bisection_search.py.


Briefly, the interpreter does not know your directory architecture.

When the interpreter get in p_03.py, the script equals:

from p_03_using_bisection_search.p_02_paying_debt_off_in_a_year import compute_balance_after

and p_03_using_bisection_search does not contain any modules or instances called p_02_paying_debt_off_in_a_year.


So I came up with a cleaner solution without changing python environment valuables (after looking up how requests do in relative import):

The main architecture of the directory is:

main.py
setup.py
problem_set_02/
   __init__.py
   p01.py
   p02.py
   p03.py

Then write in __init__.py:

from .p_02_paying_debt_off_in_a_year import compute_balance_after

Here __main__ is __init__ , it exactly refers to the module problem_set_02.

Then go to main.py:

import problem_set_02

You can also write a setup.py to add specific module to the environment.


回答 2

尝试将其运行为:

python3 -m p_03_using_bisection_search

Try to run it as:

python3 -m p_03_using_bisection_search


回答 3

您好,请按照以下步骤操作,您将解决此问题。如果已创建目录和子目录,请按照以下步骤操作,请记住,所有目录必须必须 __init__.py将其识别为目录。

  1. import sys并运行sys.path,您将能够看到python搜索的所有路径。您必须能够看到当前的工作目录。

  2. 现在,按照以下命令导入要使用import使用的子目录和相应模块:import subdir.subdir.modulename as abc现在,您可以使用该模块中的方法。 屏幕截图相同的问题

如您在此屏幕快照中看到的,我有一个父目录和两个子目录,在第二个子目录下,我有module == CommonFunction,执行sys.path后您会看到右侧,我可以看到我的工作目录

If you have created directory and sub-directory, follow the steps below and please keep in mind all directory must have __init__.py to get it recognized as a directory.

  1. In your script, include import sys and sys.path, you will be able to see all the paths available to Python. You must be able to see your current working directory.

  2. Now import sub-directory and respective module that you want to use using: import subdir.subdir.modulename as abc and now you can use the methods in that module.

As an example, you can see in this screenshot I have one parent directory and two sub-directories and under second sub-directories I have the module CommonFunction. On the right my console shows that after execution of sys.path, I can see my working directory.


回答 4

删除点并在文件开头导入absolute_import

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after

Remove the dot and import absolute_import in the beginning of your file

from __future__ import absolute_import

from p_02_paying_debt_off_in_a_year import compute_balance_after

回答 5

只需使用.py文件所在的主文件夹的名称即可。

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after

Just use the name of the main folder which the .py file is in.

from problem_set_02.p_02_paying_debt_off_in_a_year import compute_balance_after

当模块名称中带有’-‘破折号或连字符时,如何导入模块?

问题:当模块名称中带有’-‘破折号或连字符时,如何导入模块?

我想导入foo-bar.py。这有效:

foobar = __import__("foo-bar")

这不是:

from "foo-bar" import *

我的问题:有什么办法可以使用上述格式,即from "foo-bar" import *导入其中包含的模块-

I want to import foo-bar.py. This works:

foobar = __import__("foo-bar")

This does not:

from "foo-bar" import *

My question: Is there any way that I can use the above format i.e., from "foo-bar" import * to import a module that has a - in it?


回答 0

你不能。 foo-bar不是标识符。将文件重命名为foo_bar.py

编辑:如果import不是您的目标(例如:您不在乎会发生什么sys.modules,您不需要导入自身),只需将文件的所有全局变量放入自己的作用域即可,您可以使用execfile

# contents of foo-bar.py
baz = 'quux'
>>> execfile('foo-bar.py')
>>> baz
'quux'
>>> 

you can’t. foo-bar is not an identifier. rename the file to foo_bar.py

Edit: If import is not your goal (as in: you don’t care what happens with sys.modules, you don’t need it to import itself), just getting all of the file’s globals into your own scope, you can use execfile

# contents of foo-bar.py
baz = 'quux'
>>> execfile('foo-bar.py')
>>> baz
'quux'
>>> 

回答 1

如果您不能重命名模块以匹配Python命名约定,请创建一个新模块以充当中介:

 ---- foo_proxy.py ----
 tmp = __import__('foo-bar')
 globals().update(vars(tmp))

 ---- main.py ----
 from foo_proxy import * 

If you can’t rename the module to match Python naming conventions, create a new module to act as an intermediary:

 ---- foo_proxy.py ----
 tmp = __import__('foo-bar')
 globals().update(vars(tmp))

 ---- main.py ----
 from foo_proxy import * 

回答 2

从Python 3.1开始,您可以使用importlib:

import importlib  
foobar = importlib.import_module("foo-bar")

https://docs.python.org/3/library/importlib.html

Starting from Python 3.1, you can use importlib :

import importlib  
foobar = importlib.import_module("foo-bar")

( https://docs.python.org/3/library/importlib.html )


回答 3

如果您不能重命名原始文件,则还可以使用符号链接:

ln -s foo-bar.py foo_bar.py

然后,您可以:

from foo_bar import *

If you can’t rename the original file, you could also use a symlink:

ln -s foo-bar.py foo_bar.py

Then you can just:

from foo_bar import *

回答 4

就像其他人说的那样,您不能在python命名中使用“-”,有许多解决方法,其中一种这样的解决方法在必须从路径添加多个模块的情况下非常有用。 sys.path

例如,如果您的结构是这样的:

foo-bar
├── barfoo.py
└── __init__.py
import sys
sys.path.append('foo-bar')

import barfoo

Like other said you can’t use the “-” in python naming, there are many workarounds, one such workaround which would be useful if you had to add multiple modules from a path is using sys.path

For example if your structure is like this:

foo-bar
├── barfoo.py
└── __init__.py

import sys
sys.path.append('foo-bar')

import barfoo

在python中定义私有模块函数

问题:在python中定义私有模块函数

根据http://www.faqs.org/docs/diveintopython/fileinfo_private.html

像大多数语言一样,Python具有私有元素的概念:

  • 私有函数,不能从其模块外部调用

但是,如果我定义两个文件:

#a.py
__num=1

和:

#b.py
import a
print a.__num

当我运行b.py它打印出1没有给出任何exceptions。diveintopython是错误的,还是我误会了某些东西?而且是有一些方法可以定义模块的功能为私有?

According to http://www.faqs.org/docs/diveintopython/fileinfo_private.html:

Like most languages, Python has the concept of private elements:

  • Private functions, which can’t be called from outside their module

However, if I define two files:

#a.py
__num=1

and:

#b.py
import a
print a.__num

when i run b.py it prints out 1 without giving any exception. Is diveintopython wrong, or did I misunderstand something? And is there some way to do define a module’s function as private?


回答 0

在Python中,“隐私”取决于“同意成年人”的协议级别-您不能强制执行它(比现实生活中的要多;-)。单个前导下划线表示您不应该 “从外部”访问它- 两个前导下划线(不带尾随下划线)可以更加有力地传达信息……但最终,它仍然取决于社交网络会议达成共识:Python的自省是有力的,以至于你无法手铐在世界上其他程序员尊重您的意愿。

((顺便说一句,尽管这是一个秘密的秘密,但对于C ++却是如此:在大多数编译器中,狡猾的编码人员只需花#define private public一行简单#include.h代码就可以对您的“隐私”进行散列…!-) )

In Python, “privacy” depends on “consenting adults'” levels of agreement – you can’t force it (any more than you can in real life;-). A single leading underscore means you’re not supposed to access it “from the outside” — two leading underscores (w/o trailing underscores) carry the message even more forcefully… but, in the end, it still depends on social convention and consensus: Python’s introspection is forceful enough that you can’t handcuff every other programmer in the world to respect your wishes.

((Btw, though it’s a closely held secret, much the same holds for C++: with most compilers, a simple #define private public line before #includeing your .h file is all it takes for wily coders to make hash of your “privacy”…!-))


回答 1

类私有模块私有之间可能会有混淆。

模块私人与启动一个下划线
这样的元件不使用时沿复制from <module_name> import *导入命令的形式; 但是,如果使用import <moudule_name>语法将其导入(请参阅Ben Wilhelm的答案),
只需从问题示例的a .__ num中删除一个下划线,并且不会在使用该from a import *语法导入a.py的模块中显示该下划线。

类私有与开始两个下划线 (又名dunder即d-ouble下分数)
这样的变量有其名“错位”,以包括类名等
它仍然可以访问的类逻辑的外面,通过重整名称。
尽管名称改编可以用作防止未经授权访问的温和预防工具,但其主要目的是防止与祖先类的类成员发生可能的名称冲突。参见亚历克斯·马特利(Alex Martelli)有趣而准确地提及成年人的同意书,因为他描述了有关这些变量的约定。

>>> class Foo(object):
...    __bar = 99
...    def PrintBar(self):
...        print(self.__bar)
...
>>> myFoo = Foo()
>>> myFoo.__bar  #direct attempt no go
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__bar'
>>> myFoo.PrintBar()  # the class itself of course can access it
99
>>> dir(Foo)    # yet can see it
['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__
format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__
', '__subclasshook__', '__weakref__']
>>> myFoo._Foo__bar  #and get to it by its mangled name !  (but I shouldn't!!!)
99
>>>

There may be confusion between class privates and module privates.

A module private starts with one underscore
Such a element is not copied along when using the from <module_name> import * form of the import command; it is however imported if using the import <moudule_name> syntax (see Ben Wilhelm’s answer)
Simply remove one underscore from the a.__num of the question’s example and it won’t show in modules that import a.py using the from a import * syntax.

A class private starts with two underscores (aka dunder i.e. d-ouble under-score)
Such a variable has its name “mangled” to include the classname etc.
It can still be accessed outside of the class logic, through the mangled name.
Although the name mangling can serve as a mild prevention device against unauthorized access, its main purpose is to prevent possible name collisions with class members of the ancestor classes. See Alex Martelli’s funny but accurate reference to consenting adults as he describes the convention used in regards to these variables.

>>> class Foo(object):
...    __bar = 99
...    def PrintBar(self):
...        print(self.__bar)
...
>>> myFoo = Foo()
>>> myFoo.__bar  #direct attempt no go
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Foo' object has no attribute '__bar'
>>> myFoo.PrintBar()  # the class itself of course can access it
99
>>> dir(Foo)    # yet can see it
['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__
format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__
', '__subclasshook__', '__weakref__']
>>> myFoo._Foo__bar  #and get to it by its mangled name !  (but I shouldn't!!!)
99
>>>

回答 2

由于模块隐私不是纯粹的常规,并且由于使用import可能会或可能不会识别模块隐私,这取决于使用方式,因此未完全回答此问题。

如果您在模块中定义专用名称,则这些名称被导入到使用“ import module_name”语法的任何脚本中。因此,假设您已在示例中正确定义了a.py中的私有_num模块,如下所示。

#a.py
_num=1

..您将可以在b.py中使用模块名称符号访问它:

#b.py
import a
...
foo = a._num # 1

要仅从a.py导入非特权,必须使用from语法:

#b.py
from a import *
...
foo = _num # throws NameError: name '_num' is not defined

但是,为了清楚起见,从模块导入名称时最好是显式的,而不是用’*’导入所有名称:

#b.py
from a import name1 
from a import name2
...

This question was not fully answered, since module privacy is not purely conventional, and since using import may or may not recognize module privacy, depending on how it is used.

If you define private names in a module, those names will be imported into any script that uses the syntax, ‘import module_name’. Thus, assuming you had correctly defined in your example the module private, _num, in a.py, like so..

#a.py
_num=1

..you would be able to access it in b.py with the module name symbol:

#b.py
import a
...
foo = a._num # 1

To import only non-privates from a.py, you must use the from syntax:

#b.py
from a import *
...
foo = _num # throws NameError: name '_num' is not defined

For the sake of clarity, however, it is better to be explicit when importing names from modules, rather than importing them all with a ‘*’:

#b.py
from a import name1 
from a import name2
...

回答 3

Python允许带有双下划线前缀的私有成员。该技术在模块级别上不起作用,因此我认为这是Dive Into Python中的错误。

这是私有类函数的示例:

class foo():
    def bar(self): pass
    def __bar(self): pass

f = foo()
f.bar()   # this call succeeds
f.__bar() # this call fails

Python allows for private class members with the double underscore prefix. This technique doesn’t work at a module level so I am thinking this is a mistake in Dive Into Python.

Here is an example of private class functions:

class foo():
    def bar(self): pass
    def __bar(self): pass

f = foo()
f.bar()   # this call succeeds
f.__bar() # this call fails

回答 4

您可以添加一个内部函数:

def public(self, args):
   def private(self.root, data):
       if (self.root != None):
          pass #do something with data

如果您确实需要该级别的隐私,则应采用类似的方法。

You can add an inner function:

def public(self, args):
   def private(self.root, data):
       if (self.root != None):
          pass #do something with data

Something like that if you really need that level of privacy.


回答 5

这是一个古老的问题,但是标准文档现在涵盖了模块私有(一个下划线)和类私有(两个下划线)混合变量。

Python教程 » » 私有变量

This is an ancient question, but both module private (one underscore) and class-private (two underscores) mangled variables are now covered in the standard documentation:

The Python Tutorial » Classes » Private Variables


回答 6

嵌入闭包或函数是一种方法。这在JS中很常见,但非浏览器平台或浏览器工作程序则不需要。

在Python中,这似乎有些奇怪,但是如果确实需要隐藏某些东西,那可能就是这样。更重要的是,使用python API并保留需要隐藏在C(或其他语言)中的内容可能是最好的方法。如果没有,我会将代码放入函数中,调用该函数并使它返回要导出的项目。

embedded with closures or functions is one way. This is common in JS although not required for non-browser platforms or browser workers.

In Python it seems a bit strange, but if something really needs to be hidden than that might be the way. More to the point using the python API and keeping things that require to be hidden in the C (or other language) is probably the best way. Failing that I would go for putting the code inside a function, calling that and having it return the items you want to export.


回答 7

Python具有三种模式,分别是private,public和protected。在导入模块时,只能访问public模式。因此,不能从模块外部(即在导入时)调用private和protected模块。

Python has three modes via., private, public and protected .While importing a module only public mode is accessible .So private and protected modules cannot be called from outside of the module i.e., when it is imported .


Python 3:ImportError“没有名为Setuptools的模块”

问题:Python 3:ImportError“没有名为Setuptools的模块”

我在使用Python 3安装软件包时遇到了麻烦。

我一直都使用来安装软件包setup.py install。但是现在,当我尝试安装ansicolors软件包时,我得到了:

importerror“没有名为Setuptools的模块”

我不知道该怎么办,因为过去我没有安装过setuptools。尽管如此,我仍然能够在setup.py install没有setuptools的情况下安装许多软件包。为什么现在应该获得setuptools?

我什至无法安装setuptools,因为我有Python 3.3,setuptools不支持Python 3。

为什么我的安装命令不再起作用?

I’m having troubles with installing packages in Python 3.

I have always installed packages with setup.py install. But now, when I try to install the ansicolors package I get:

importerror “No Module named Setuptools”

I have no idea what to do because I didn’t have setuptools installed in the past. Still, I was able to install many packages with setup.py install without setuptools. Why should I get setuptools now?

I can’t even install setuptools because I have Python 3.3 and setuptools doesn’t support Python 3.

Why doesn’t my install command work anymore?


回答 0

您的setup.py文件需要setuptools。一些Python软件包曾经distutils用于分发,但现在大多数都使用setuptools了一个更完整的软件包。是有关它们之间差异的问题。

setuptools在Debian上安装:

sudo apt-get install python3-setuptools

对于旧版本的Python(Python 2.x):

sudo apt-get install python-setuptools

Your setup.py file needs setuptools. Some Python packages used to use distutils for distribution, but most now use setuptools, a more complete package. Here is a question about the differences between them.

To install setuptools on Debian:

sudo apt-get install python3-setuptools

For an older version of Python (Python 2.x):

sudo apt-get install python-setuptools

回答 1

编辑:官方setuptools dox页面

如果您从python.org安装了Python 2> = 2.7.9或Python 3> = 3.4,则已经具有pip和setuptools,但需要升级到最新版本:

在Linux或OS X上:

pip install -U pip setuptools 

在Windows上:

python -m pip install -U pip setuptools

因此,本文的其余部分可能已过时(例如,某些链接不起作用)。

分发 -是setuptools分支,可“提供Python 3支持”。Distribution(setuptools)+ pip的安装说明:

curl -O http://python-distribute.org/distribute_setup.py
python distribute_setup.py
easy_install pip

这里有类似的问题。

更新:分发似乎已过时,即已合并到Setuptools中:分发是Setuptools项目不推荐使用的分支。从Setuptools 0.7发行版开始,Setuptools和Distribute已合并,并且不再维护Distribute。所有正在进行的工作应参考Setuptools项目和Setuptools文档。

您可以尝试在setuptools pypi页面上找到说明(我尚未对此进行测试,对不起:():

wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
easy_install pip

EDIT: Official setuptools dox page:

If you have Python 2 >=2.7.9 or Python 3 >=3.4 installed from python.org, you will already have pip and setuptools, but will need to upgrade to the latest version:

On Linux or OS X:

pip install -U pip setuptools 

On Windows:

python -m pip install -U pip setuptools

Therefore the rest of this post is probably obsolete (e.g. some links don’t work).

Distribute – is a setuptools fork which “offers Python 3 support”. Installation instructions for distribute(setuptools) + pip:

curl -O http://python-distribute.org/distribute_setup.py
python distribute_setup.py
easy_install pip

Similar issue here.

UPDATE: Distribute seems to be obsolete, i.e. merged into Setuptools: Distribute is a deprecated fork of the Setuptools project. Since the Setuptools 0.7 release, Setuptools and Distribute have merged and Distribute is no longer being maintained. All ongoing effort should reference the Setuptools project and the Setuptools documentation.

You may try with instructions found on setuptools pypi page (I haven’t tested this, sorry :( ):

wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
easy_install pip

回答 2

我在使用python-2.6的Oracle Linux 6.4上的virtualenv内执行此操作,因此基于apt的解决方案对我来说不是一个选择,python-2.7的想法也不对。我的解决方法是升级我由virtualenv安装的setuptools版本:

pip install --upgrade setuptools

之后,我能够将软件包安装到virtualenv中。我知道这个问题已经选择了答案,但我希望这个答案对我的情况有所帮助。

I was doing this inside a virtualenv on Oracle Linux 6.4 using python-2.6 so the apt-based solutions weren’t an option for me, nor were the python-2.7 ideas. My fix was to upgrade my version of setuptools that had been installed by virtualenv:

pip install --upgrade setuptools

After that, I was able to install packages into the virtualenv. I know this question has already had an answer selected but I hope this answer will help others in my situation.


回答 3

pip uninstall setuptools

然后:

pip install setuptools

这对我有用,并解决了我的问题。

pip uninstall setuptools

and then:

pip install setuptools

This works for me and fix my issue.


回答 4

distribute软件包提供了与Python 3兼容的版本setuptoolshttp : //pypi.python.org/pypi/distribute

另外,用于pip安装模块。它会自动找到依赖项并为您安装它们。

对于您的包裹,它对我来说效果很好:

[~] pip --version                                                              
pip 1.2.1 from /usr/lib/python3.3/site-packages (python 3.3)
[~] sudo pip install ansicolors                                                
Downloading/unpacking ansicolors
  Downloading ansicolors-1.0.2.tar.gz
  Running setup.py egg_info for package ansicolors

Installing collected packages: ansicolors
  Running setup.py install for ansicolors

Successfully installed ansicolors
Cleaning up...
[~]

The distribute package provides a Python 3-compatible version of setuptools: http://pypi.python.org/pypi/distribute

Also, use pip to install the modules. It automatically finds dependencies and installs them for you.

It works just fine for me with your package:

[~] pip --version                                                              
pip 1.2.1 from /usr/lib/python3.3/site-packages (python 3.3)
[~] sudo pip install ansicolors                                                
Downloading/unpacking ansicolors
  Downloading ansicolors-1.0.2.tar.gz
  Running setup.py egg_info for package ansicolors

Installing collected packages: ansicolors
  Running setup.py install for ansicolors

Successfully installed ansicolors
Cleaning up...
[~]

回答 5

Windows 7的:

我在这里为python selenium webdriver 提供了完整的解决方案

1. Setup easy install (windows - simplified)
    a. download ez.setup.py (https://bootstrap.pypa.io/ez_setup.py) from 'https://pypi.python.org/pypi/setuptools'
    b. move ez.setup.py to C:\Python27\
    c. open cmd prompt
    d. cd C:\Python27\
    e. C:\Python27\python.exe ez.setup.py install

Windows 7:

I have given a complete solution here for python selenium webdriver

1. Setup easy install (windows - simplified)
    a. download ez.setup.py (https://bootstrap.pypa.io/ez_setup.py) from 'https://pypi.python.org/pypi/setuptools'
    b. move ez.setup.py to C:\Python27\
    c. open cmd prompt
    d. cd C:\Python27\
    e. C:\Python27\python.exe ez.setup.py install

回答 6

PyPA推荐的用于安装和管理Python包的工具pippip包括在Python 3.4(PEP 453),但对于旧版本这里是如何安装它(在Windows上):

下载https://bootstrap.pypa.io/get-pip.py

>c:\Python33\python.exe get-pip.py
Downloading/unpacking pip
Downloading/unpacking setuptools
Installing collected packages: pip, setuptools
Successfully installed pip setuptools
Cleaning up...

>c:\Python33\Scripts\pip.exe install pymysql
Downloading/unpacking pymysql
Installing collected packages: pymysql
Successfully installed pymysql
Cleaning up...

The PyPA recommended tool for installing and managing Python packages is pip. pip is included with Python 3.4 (PEP 453), but for older versions here’s how to install it (on Windows):

Download https://bootstrap.pypa.io/get-pip.py

>c:\Python33\python.exe get-pip.py
Downloading/unpacking pip
Downloading/unpacking setuptools
Installing collected packages: pip, setuptools
Successfully installed pip setuptools
Cleaning up...

>c:\Python33\Scripts\pip.exe install pymysql
Downloading/unpacking pymysql
Installing collected packages: pymysql
Successfully installed pymysql
Cleaning up...

回答 7

几年前,我继承了在Django-1.2.3下运行的python(2.7.1)项目,现在被要求使用QR增强功能。遇到了同样的问题,没有找到pip或apt-get。所以我以完全不同但简单的方式解决了它。我/ bin / vi-ed setup.py,并将“ from setuptools import setup”这一行更改为:“ from distutils.core import setup”对我而言,所以我认为我应该将它发布给其他运行旧python的用户。问候,罗杰·维米尔

A few years ago I inherited a python (2.7.1) project running under Django-1.2.3 and now was asked to enhance it with QR possibilities. Got the same problem and did not find pip or apt-get either. So I solved it in a totally different but easy way. I /bin/vi-ed the setup.py and changed the line “from setuptools import setup” into: “from distutils.core import setup” That did it for me, so I thought I should post this for other users running old pythons. Regards, Roger Vermeir


我无法安装python-ldap

问题:我无法安装python-ldap

当我运行以下命令时:

sudo pip install python-ldap

我收到此错误:

在Modules / LDAPObject.c:9包含的文件中:

Modules / errors.h:8:致命错误:lber.h:没有此类文件或目录

任何想法如何解决这一问题?

When I run the following command:

sudo pip install python-ldap

I get this error:

In file included from Modules/LDAPObject.c:9:

Modules/errors.h:8: fatal error: lber.h: No such file or directory

Any ideas how to fix this?


回答 0

Python,LDAP是基于OpenLDAP的,所以你必须为了编译Python模块的开发文件(头)。如果您使用的是Ubuntu,则该软件包称为libldap2-dev

Debian / Ubuntu

sudo apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev

RedHat / CentOS

sudo yum install python-devel openldap-devel

The python-ldap is based on OpenLDAP, so you need to have the development files (headers) in order to compile the Python module. If you’re on Ubuntu, the package is called libldap2-dev.

Debian/Ubuntu:

sudo apt-get install libsasl2-dev python-dev libldap2-dev libssl-dev

RedHat/CentOS:

sudo yum install python-devel openldap-devel

回答 1

要使用pip成功安装python-ldap,需要以下开发库(软件包名称取自ubuntu环境):

sudo apt-get install -y python-dev libldap2-dev libsasl2-dev libssl-dev

To install python-ldap successfully with pip, following development libraries are needed (package names taken from ubuntu environment):

sudo apt-get install -y python-dev libldap2-dev libsasl2-dev libssl-dev

回答 2

在CentOS / RHEL 6上,您需要安装:

sudo yum install python-devel
sudo yum install openldap-devel

yum也将cyrus-sasl-devel作为依赖项安装。然后,您可以运行:

pip-2.7 install python-ldap

On CentOS/RHEL 6, you need to install:

sudo yum install python-devel
sudo yum install openldap-devel

and yum will also install cyrus-sasl-devel as a dependency. Then you can run:

pip-2.7 install python-ldap

回答 3

在Ubuntu中,它看起来像这样:

 $ sudo apt-get install python-dev libldap2-dev libsasl2-dev libssl-dev
 $ sudo pip install python-ldap

In Ubuntu it looks like this :

 $ sudo apt-get install python-dev libldap2-dev libsasl2-dev libssl-dev
 $ sudo pip install python-ldap

回答 4

Windows:我完全同意接受的答案,但是仔细阅读评论需要花一些时间才能弄清我需要的内容。我使用Bitnami在Windows上的Reviewboard上遇到了这个特定问题。为了给出Windows的答案,我使用了注释中提到的以下链接:

然后,执行以下命令

easy_install pip
pip install python_ldap-2.4.20-cp27-none_win32.whl

(因为我当时安装了python 2.7和32位安装程序)

easy_install python-ldap

Windows: I completely agree with the accepted answer, but digging through the comments took a while to get to the meat of what I needed. I ran across this specific problem with Reviewboard on Windows using the Bitnami. To give an answer for windows then, I used this link mentioned in the comments:

Then, executed the following commands

easy_install pip
pip install python_ldap-2.4.20-cp27-none_win32.whl

(because I had python 2.7 and a 32bit install at that)

easy_install python-ldap

回答 5

“不要盲目删除/安装软件”

在基于Ubuntu / Debian的发行版中,您可以apt-file用来查找包含缺少的头文件的确切软件包的名称。

# do this once
sudo apt-get install apt-file
sudo apt-file update

$ apt-file search lber.h
libldap2-dev: /usr/include/lber.h

从输出可以看到apt-file search lber.h,您只需要安装软件包libldap2-dev

sudo apt-get install libldap2-dev

“Don’t blindly remove/install software”

In a Ubuntu/Debian based distro, you could use apt-file to find the name of the exact package that includes the missing header file.

# do this once
sudo apt-get install apt-file
sudo apt-file update

$ apt-file search lber.h
libldap2-dev: /usr/include/lber.h

As you could see from the output of apt-file search lber.h, you’d just need to install the package libldap2-dev.

sudo apt-get install libldap2-dev

回答 6

对于那些在Alpine Linux上也缺少Iber.h的问题,例如,您尝试在Docker映像中尝试适应Alpine。

您要查找的软件包是:openldap-dev

所以跑

apk add openldap-dev

从版本3.3到Edge可用

适用于armhf和x86_64体系结构。

For those having the same issue of missing Iber.h on Alpine Linux, in a docker image that you are trying to adapt to Alpine for instance.

The package you are looking for is: openldap-dev

So run

apk add openldap-dev

Available from version 3.3 up to Edge

Available for both armhf and x86_64 Architectures.


回答 7

在openSUSE需要安装的软件包openldap2-develcyrus-sasl-develpython-devellibopenssl-devel

zypper install openldap2-devel cyrus-sasl-devel python-devel libopenssl-devel

On openSUSE you need to install the packages openldap2-devel, cyrus-sasl-devel, python-devel and libopenssl-devel.

zypper install openldap2-devel cyrus-sasl-devel python-devel libopenssl-devel


回答 8

在Fedora 22上,您需要执行以下操作:

sudo dnf install python-devel
sudo dnf install openldap-devel

On Fedora 22, you need to do this instead:

sudo dnf install python-devel
sudo dnf install openldap-devel

回答 9

在OSX上,您需要xcode CLI工具。只需打开一个终端并运行:

xcode-select --install

On OSX, you need the xcode CLI tools. Just open a terminal and run:

xcode-select --install

回答 10

对于大多数系统,现在在python-ldap的文档的“安装”部分中提到了构建要求。

如果您的系统缺少任何内容(或系统完全丢失),请告知维护人员!(截至2018年,我是维护者,因此在此处进行评论应该足够。或者您可以发送拉取请求或邮件。)

For most systems, the build requirements are now mentioned in python-ldap’s documentation, in the “Installing” section.

If anything is missing for your system (or your system is missing entirely), please let maintainer know! (As of 2018, I am the maintainer, so a comment here should be enough. Or you can send a pull request or mail.)


回答 11

python3不支持python-ldap。而是安装ldap3。

python3 does not support python-ldap. Rather to install ldap3.


回答 12

要更正由于依赖而导致的错误,请安装python-ldap:Windows 7/10

下载whl文件

http://www.lfd.uci.edu/~gohlke/pythonlibs/#python-ldap

python 3.6适合

python_ldap-3.2.0-cp36-cp36m-win_amd64.whl

将文件部署到:

c:\ python36 \ Scripts \

用安装

python -m pip install python_ldap-3.2.0-cp36-cp36m-win_amd64.whl

To correct the error due to dependencies to install the python-ldap : Windows 7/10

download the whl file

http://www.lfd.uci.edu/~gohlke/pythonlibs/#python-ldap.

python 3.6 suit with

python_ldap-3.2.0-cp36-cp36m-win_amd64.whl

Deploy the file in :

c:\python36\Scripts\

install it with

python -m pip install python_ldap-3.2.0-cp36-cp36m-win_amd64.whl

回答 13

在FreeBSD 11中:

pkg install openldap-client # for lber.h
pkg install cyrus-sasl # if you need sasl.h
pip install python-ldap

In FreeBSD 11:

pkg install openldap-client # for lber.h
pkg install cyrus-sasl # if you need sasl.h
pip install python-ldap

回答 14

作为在Debian / Ubuntu上安装具有二进制依赖性[1]的Python软件包的一般解决方案:

sudo apt-get build-dep python-ldap
# installs system dependencies (but not the package itself)
pew workon my_virtualenv # enter your virtualenv
pip install python-ldap

您必须在Ubuntu和PyPI 检查Python软件包名称。在这种情况下,它们是相同的。

如果Python软件包不在Ubuntu仓库中,显然不起作用。

[1]我尝试pip install matplotlib在Ubuntu上学习了这个技巧。

As a general solution to install Python packages with binary dependencies [1] on Debian/Ubuntu:

sudo apt-get build-dep python-ldap
# installs system dependencies (but not the package itself)
pew workon my_virtualenv # enter your virtualenv
pip install python-ldap

You’ll have to check the name of your Python package on Ubuntu versus PyPI. In this case they’re the same.

Obviously doesn’t work if the Python package is not in the Ubuntu repos.

[1] I learnt this trick when trying to pip install matplotlib on Ubuntu.


回答 15

对于高山码头工人

apk add openldap-dev

如果python版本是3以上,请尝试

pip install python3-ldap

For alpine docker

apk add openldap-dev

if the python version is 3 and above try

pip install python3-ldap

回答 16

如果您使用的是Windows计算机,则可以在此链接中找到“ python-ldap”轮,然后进行安装

If you’re working with windows machines, you can find ‘python-ldap’ wheel in this Link and then you can install it


回答 17

对于使用alphine linux的用户,apk添加openldap-dev

for those who are using alphine linux, apk add openldap-dev


回答 18

sudo apt-get install build-essential python3-dev python2.7-dev libldap2-dev libsasl2-dev slapd ldap-utils python-tox lcov valgrind
sudo apt-get install build-essential python3-dev python2.7-dev libldap2-dev libsasl2-dev slapd ldap-utils python-tox lcov valgrind

从父文件夹导入模块

问题:从父文件夹导入模块

我正在运行Python 2.5。

这是我的文件夹树:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(我还在__init__.py每个文件夹中,为便于阅读,在此省略)

如何nib从模块内部导入life模块?我希望无需修补sys.path就可以做到。

注意:正在运行的主模块在ptdraft文件夹中。

I am running Python 2.5.

This is my folder tree:

ptdraft/
  nib.py
  simulations/
    life/
      life.py

(I also have __init__.py in each folder, omitted here for readability)

How do I import the nib module from inside the life module? I am hoping it is possible to do without tinkering with sys.path.

Note: The main module being run is in the ptdraft folder.


回答 0

看来问题与该模块位于父目录或类似目录中无关。

您需要将包含的目录添加ptdraft到PYTHONPATH

您说过import nib与您合作,这可能意味着您将ptdraft自身(而不是其父项)添加到了PYTHONPATH中。

It seems that the problem is not related to the module being in a parent directory or anything like that.

You need to add the directory that contains ptdraft to PYTHONPATH

You said that import nib worked with you, that probably means that you added ptdraft itself (not its parent) to PYTHONPATH.


回答 1

您可以使用相对导入(python> = 2.5):

from ... import nib

(Python 2.5的新增功能)PEP 328:绝对导入和相对导入

编辑:添加了另一个点“。” 上两个包

You could use relative imports (python >= 2.5):

from ... import nib

(What’s New in Python 2.5) PEP 328: Absolute and Relative Imports

EDIT: added another dot ‘.’ to go up two packages


回答 2

相对导入(如中的from .. import mymodule)仅在包中起作用。要导入当前模块的父目录中的“ mymodule”:

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir) 

import mymodule

编辑__file__属性并不总是给定的。os.path.abspath(__file__)我现在建议不要使用Inspect模块来检索当前文件的文件名(和路径),而不要使用它

Relative imports (as in from .. import mymodule) only work in a package. To import ‘mymodule’ that is in the parent directory of your current module:

import os,sys,inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0,parentdir) 

import mymodule

edit: the __file__ attribute is not always given. Instead of using os.path.abspath(__file__) I now suggested using the inspect module to retrieve the filename (and path) of the current file


回答 3

对于同级软件包的导入问题,我也发表了类似的答案。你可以在这里看到它。

没有sys.path黑客的解决方案

摘要

  • 将代码包装到一个文件夹中(例如packaged_stuff
  • setup.py在使用setuptools.setup()的地方使用创建脚本。
  • 使用以下命令以可编辑状态安装软件包 pip install -e <myproject_folder>
  • 导入使用 from packaged_stuff.modulename import function_name

设定

我假设与问题中的文件夹结构相同

.
└── ptdraft
    ├── __init__.py
    ├── nib.py
    └── simulations
        ├── __init__.py
        └── life
            ├── __init__.py
            └── life.py

我将其.称为根文件夹,就我而言,它位于中C:\tmp\test_imports

脚步

1)将A添加setup.py到根文件夹

的内容setup.py可以很简单

from setuptools import setup, find_packages

setup(name='myproject', version='1.0', packages=find_packages())

基本上是“任何” setup.py都可以。这只是一个最小的工作示例。

2)使用虚拟环境

如果您熟悉虚拟环境,请激活一个,然后跳到下一步。虚拟环境的使用不是绝对必需的,但从长远来看(当您正在进行多个项目时),它们确实可以帮助您。最基本的步骤是(在根文件夹中运行)

  • 创建虚拟环境
    • python -m venv venv
  • 激活虚拟环境
    • . /venv/bin/activate(Linux)或./venv/Scripts/activate(Win)

要了解更多有关此的信息,只需在Google上搜索“ python virtualenv教程”或类似内容即可。除了创建,激活和停用之外,您可能根本不需要任何其他命令。

创建并激活虚拟环境后,控制台应在括号中提供虚拟环境的名称。

PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>

3)pip以可编辑状态安装项目

安装您的顶级包myproject使用pip。诀窍是-e在执行安装时使用标志。这样,它以可编辑状态安装,并且对.py文件所做的所有编辑将自动包含在已安装的软件包中。

在根目录中,运行

pip install -e . (注意点,它代表“当前目录”)

您还可以看到它是通过使用安装的 pip freeze

(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
  Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0

4)通过mainfolder在每次导入之前进行导入

在此示例中,mainfolder将为ptdraft。这样的好处是您不会与其他模块名称(来自python标准库或3rd party模块)发生名称冲突。


用法示例

笔尖

def function_from_nib():
    print('I am the return value from function_from_nib!')

life.py

from ptdraft.nib import function_from_nib

if __name__ == '__main__':
    function_from_nib()

运行life.py

(venv) PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!

I posted a similar answer also to the question regarding imports from sibling packages. You can see it here.

Solution without sys.path hacks

Summary

  • Wrap the code into one folder (e.g. packaged_stuff)
  • Use create setup.py script where you use setuptools.setup().
  • Pip install the package in editable state with pip install -e <myproject_folder>
  • Import using from packaged_stuff.modulename import function_name

Setup

I assume the same folder structure as in the question

.
└── ptdraft
    ├── __init__.py
    ├── nib.py
    └── simulations
        ├── __init__.py
        └── life
            ├── __init__.py
            └── life.py

I call the . the root folder, and in my case it is located in C:\tmp\test_imports.

Steps

1) Add a setup.py to the root folder

The contents of the setup.py can be simply

from setuptools import setup, find_packages

setup(name='myproject', version='1.0', packages=find_packages())

Basically “any” setup.py would work. This is just a minimal working example.

2) Use a virtual environment

If you are familiar with virtual environments, activate one, and skip to the next step. Usage of virtual environments are not absolutely required, but they will really help you out in the long run (when you have more than 1 project ongoing..). The most basic steps are (run in the root folder)

  • Create virtual env
    • python -m venv venv
  • Activate virtual env
    • . /venv/bin/activate (Linux) or ./venv/Scripts/activate (Win)

To learn more about this, just Google out “python virtualenv tutorial” or similar. You probably never need any other commands than creating, activating and deactivating.

Once you have made and activated a virtual environment, your console should give the name of the virtual environment in parenthesis

PS C:\tmp\test_imports> python -m venv venv
PS C:\tmp\test_imports> .\venv\Scripts\activate
(venv) PS C:\tmp\test_imports>

3) pip install your project in editable state

Install your top level package myproject using pip. The trick is to use the -e flag when doing the install. This way it is installed in an editable state, and all the edits made to the .py files will be automatically included in the installed package.

In the root directory, run

pip install -e . (note the dot, it stands for “current directory”)

You can also see that it is installed by using pip freeze

(venv) PS C:\tmp\test_imports> pip install -e .
Obtaining file:///C:/tmp/test_imports
Installing collected packages: myproject
  Running setup.py develop for myproject
Successfully installed myproject
(venv) PS C:\tmp\test_imports> pip freeze
myproject==1.0

4) Import by prepending mainfolder to every import

In this example, the mainfolder would be ptdraft. This has the advantage that you will not run into name collisions with other module names (from python standard library or 3rd party modules).


Example Usage

nib.py

def function_from_nib():
    print('I am the return value from function_from_nib!')

life.py

from ptdraft.nib import function_from_nib

if __name__ == '__main__':
    function_from_nib()

Running life.py

(venv) PS C:\tmp\test_imports> python .\ptdraft\simulations\life\life.py
I am the return value from function_from_nib!

回答 4

您可以在sys.path中列出的“模块搜索路径”中使用取决于OS的路径。因此您可以轻松添加父目录,如下所示

import sys
sys.path.insert(0,'..')

如果您要添加父/母目录,

sys.path.insert(0,'../..')

这在python 2和3。

You can use OS depending path in “module search path” which is listed in sys.path . So you can easily add parent directory like following

import sys
sys.path.insert(0,'..')

If you want to add parent-parent directory,

sys.path.insert(0,'../..')

This works both in python 2 and 3.


回答 5

如果无法将模块文件夹添加到PYTHONPATH,则可以在程序中修改sys.path列表,Python解释程序会在其中搜索要导入的模块,python文档说:

导入名为spam的模块时,解释器首先搜索具有该名称的内置模块。如果找不到,它将在变量sys.path给出的目录列表中搜索名为spam.py的文件。sys.path从以下位置初始化:

  • 包含输入脚本的目录(或当前目录)。
  • PYTHONPATH(目录名称列表,语法与shell变量PATH相同)。
  • 取决于安装的默认值。

初始化之后,Python程序可以修改sys.path。包含正在运行的脚本的目录位于搜索路径的开始,在标准库路径之前。这意味着将加载该目录中的脚本,而不是库目录中相同名称的模块。除非打算进行更换,否则这是一个错误。

知道了这一点,您可以在程序中执行以下操作:

import sys
# Add the ptdraft folder path to the sys.path list
sys.path.append('/path/to/ptdraft/')

# Now you can import your module
from ptdraft import nib
# Or just
import ptdraft

If adding your module folder to the PYTHONPATH didn’t work, You can modify the sys.path list in your program where the Python interpreter searches for the modules to import, the python documentation says:

When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

  • the directory containing the input script (or the current directory).
  • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
  • the installation-dependent default.

After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended.

Knowing this, you can do the following in your program:

import sys
# Add the ptdraft folder path to the sys.path list
sys.path.append('/path/to/ptdraft/')

# Now you can import your module
from ptdraft import nib
# Or just
import ptdraft

回答 6

对python 2不太了解。
在python 3中,可以按以下方式添加父文件夹:

import sys 
sys.path.append('..')

…然后可以从中导入模块

Don’t know much about python 2.
In python 3, the parent folder can be added as follows:

import sys 
sys.path.append('..')

…and then one is able to import modules from it


回答 7

这是一个简单的答案,因此您可以了解它的工作原理(小型和跨平台)。
它仅使用内置模块(ossysinspect),所以应该工作
在任何操作系统(OS),因为Python是专为上。

较短的答案代码-更少的行和变量

from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module  # Replace "my_module" here with the module name.
sys.path.pop(0)

如果少于此行,请用替换第二行import os.path as path, sys, inspect,在(第3行)的开头
添加inspect.getsourcefile然后删除第一行。
-但是,这会导入所有模块,因此可能需要更多的时间,内存和资源。

我的答案的代码(较长版本

from inspect import getsourcefile
import os.path
import sys

current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]

sys.path.insert(0, parent_dir)

import my_module  # Replace "my_module" here with the module name.

它使用来自Stack Overflow答案的示例。如何获取
Python中当前执行文件的路径?
使用内置工具查找正在运行的代码的源(文件名)。

from inspect import getsourcefile  
from os.path import abspath  

接下来,无论您想在哪里找到源文件,都只需使用:

abspath(getsourcefile(lambda:0))

我的代码sys.path在的python路径列表中添加了文件路径
因为这允许Python从该文件夹导入模块。

在代码中导入模块之后, 当添加的文件夹中的模块名称与另一个 稍后在程序中导入的模块同名时,最好sys.path.pop(0)换行运行。您需要删除导入之前添加的列表项,而不是其他路径。 如果您的程序未导入其他模块,则不删除文件路径是安全的,因为 在程序结束(或重新启动Python Shell)之后,对



sys.path消失。

有关文件名变量的注释

我的答案没有使用__file__变量来获取正在运行的
代码的文件路径/文件名,因为此处的用户经常将其描述为不可靠的。您不应将其
用于其他人使用的程序中从父文件夹导入模块

一些不起作用的示例(引用 Stack Overflow问题):

• 在某些平台找不到•有时不是完整的文件路径

  • py2exe没有__file__属性,但是有一种解决方法
  • 当您从IDLE运行时,execute()没有__file__属性
  • 我得到的OS X 10.6 NameError: global name '__file__' is not defined

Here is an answer that’s simple so you can see how it works, small and cross-platform.
It only uses built-in modules (os, sys and inspect) so should work
on any operating system (OS) because Python is designed for that.

Shorter code for answer – fewer lines and variables

from inspect import getsourcefile
import os.path as path, sys
current_dir = path.dirname(path.abspath(getsourcefile(lambda:0)))
sys.path.insert(0, current_dir[:current_dir.rfind(path.sep)])
import my_module  # Replace "my_module" here with the module name.
sys.path.pop(0)

For less lines than this, replace the second line with import os.path as path, sys, inspect,
add inspect. at the start of getsourcefile (line 3) and remove the first line.
– however this imports all of the module so could need more time, memory and resources.

The code for my answer (longer version)

from inspect import getsourcefile
import os.path
import sys

current_path = os.path.abspath(getsourcefile(lambda:0))
current_dir = os.path.dirname(current_path)
parent_dir = current_dir[:current_dir.rfind(os.path.sep)]

sys.path.insert(0, parent_dir)

import my_module  # Replace "my_module" here with the module name.

It uses an example from a Stack Overflow answer How do I get the path of the current
executed file in Python?
to find the source (filename) of running code with a built-in tool.

from inspect import getsourcefile  
from os.path import abspath  

Next, wherever you want to find the source file from you just use:

abspath(getsourcefile(lambda:0))

My code adds a file path to sys.path, the python path list
because this allows Python to import modules from that folder.

After importing a module in the code, it’s a good idea to run sys.path.pop(0) on a new line
when that added folder has a module with the same name as another module that is imported
later in the program. You need to remove the list item added before the import, not other paths.
If your program doesn’t import other modules, it’s safe to not delete the file path because
after a program ends (or restarting the Python shell), any edits made to sys.path disappear.

Notes about a filename variable

My answer doesn’t use the __file__ variable to get the file path/filename of running
code because users here have often described it as unreliable. You shouldn’t use it
for importing modules from parent folder in programs used by other people.

Some examples where it doesn’t work (quote from this Stack Overflow question):

• it can’t be found on some platforms • it sometimes isn’t the full file path

  • py2exe doesn’t have a __file__ attribute, but there is a workaround
  • When you run from IDLE with execute() there is no __file__ attribute
  • OS X 10.6 where I get NameError: global name '__file__' is not defined

回答 8

这是更通用的解决方案,其中将父目录包含在sys.path中(对我有用):

import os.path, sys
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

Here is more generic solution that includes the parent directory into sys.path (works for me):

import os.path, sys
sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))

回答 9

我发现以下方法可用于从脚本的父目录导入包。在示例中,我想env.pyapp.db包中导入函数。

.
└── my_application
    └── alembic
        └── env.py
    └── app
        ├── __init__.py
        └── db
import os
import sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)

I found the following way works for importing a package from the script’s parent directory. In the example, I would like to import functions in env.py from app.db package.

.
└── my_application
    └── alembic
        └── env.py
    └── app
        ├── __init__.py
        └── db
import os
import sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)

回答 10

上述解决方案也很好。解决此问题的另一种方法是

如果要从顶层目录导入任何内容。然后,

from ...module_name import *

另外,如果要从父目录导入任何模块。然后,

from ..module_name import *

另外,如果要从父目录导入任何模块。然后,

from ...module_name.another_module import *

这样,您可以根据需要导入任何特定方法。

Above mentioned solutions are also fine. Another solution to this problem is

If you want to import anything from top level directory. Then,

from ...module_name import *

Also, if you want to import any module from the parent directory. Then,

from ..module_name import *

Also, if you want to import any module from the parent directory. Then,

from ...module_name.another_module import *

This way you can import any particular method if you want to.


回答 11

对我来说,访问父目录最短和最喜欢的oneliner是:

sys.path.append(os.path.dirname(os.getcwd()))

要么:

sys.path.insert(1, os.path.dirname(os.getcwd()))

os.getcwd()返回当前工作目录的名称,os.path.dirname(directory_name)返回所传递目录的目录名称。

实际上,在我看来,Python项目体系结构应采用以下方式:子目录中的任何模块都不会使用父目录中的任何模块。如果发生这种情况,则值得重新考虑项目树。

另一种方法是将父目录添加到PYTHONPATH系统环境变量。

For me the shortest and my favorite oneliner for accessing to the parent directory is:

sys.path.append(os.path.dirname(os.getcwd()))

or:

sys.path.insert(1, os.path.dirname(os.getcwd()))

os.getcwd() returns the name of the current working directory, os.path.dirname(directory_name) returns the directory name for the passed one.

Actually, in my opinion Python project architecture should be done the way where no one module from child directory will use any module from the parent directory. If something like this happens it is worth to rethink about the project tree.

Another way is to add parent directory to PYTHONPATH system environment variable.


回答 12

在Jupyter笔记本中

只要您在Jupyter Notebook中工作,这个简短的解决方案就可能有用:

%cd ..
import nib

即使没有__init__.py文件也可以使用。

我在Linux和Windows 7上使用Anaconda3对其进行了测试。

In a Jupyter Notebook

As long as you’re working in a Jupyter Notebook, this short solution might be useful:

%cd ..
import nib

It works even without an __init__.py file.

I tested it with Anaconda3 on Linux and Windows 7.


回答 13

import sys sys.path.append('../')

import sys sys.path.append('../')


回答 14

当不在带有__init__.py文件的打包环境中时,pathlib库(包含在> = Python 3.4中)使将父目录的路径附加到PYTHONPATH变得非常简洁直观:

import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))

When not being in a package environment with __init__.py files the pathlib library (included with >= Python 3.4) makes it very concise and intuitive to append the path of the parent directory to the PYTHONPATH:

import sys
from pathlib import Path
sys.path.append(str(Path('.').absolute().parent))

回答 15

与过去的答案相同的风格-但行数较少:P

import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)

文件返回您正在工作的位置

same sort of style as the past answer – but in fewer lines :P

import os,sys
parentdir = os.path.dirname(__file__)
sys.path.insert(0,parentdir)

file returns the location you are working in


回答 16

使用库。创建一个名为nib的库,使用setup.py安装它,使其驻留在站点程序包中,您的问题将得到解决。您不必将自己制作的所有东西都塞进一个包装中。分解成碎片。

Work with libraries. Make a library called nib, install it using setup.py, let it reside in site-packages and your problems are solved. You don’t have to stuff everything you make in a single package. Break it up to pieces.


回答 17

在Linux系统中,您可以创建一个从“ life”文件夹到nib.py文件的软链接。然后,您可以像这样简单地导入它:

import nib

In a Linux system, you can create a soft link from the “life” folder to the nib.py file. Then, you can simply import it like:

import nib