首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当外部库导入依赖项时,本地文件优先

当外部库导入依赖项时,本地文件优先
EN

Stack Overflow用户
提问于 2018-08-08 17:23:23
回答 1查看 309关注 0票数 2

我有两个本地文件,strategy.pysignal.py

代码语言:javascript
复制
$ ls -1 ~/src/foo
signal.py
strategy.py

strategy.py**:**

代码语言:javascript
复制
$ cat strategy.py
import numpy

signal.py**:**

代码语言:javascript
复制
$ cat signal.py 
import talib

除了这些单一的导入行,否则这两个文件都是空的。

当我尝试运行strategy.py时,当numpy的依赖项尝试import signal时,本地signal.py优先

代码语言:javascript
复制
$ python strategy.py 
Traceback (most recent call last):
  File "strategy.py", line 1, in <module>
    import numpy
  ...
  File "/home/steve/src/foo/.venv/lib/python3.6/site-packages/numpy/testing/__init__.py", line 10, in <module>
    from unittest import TestCase
  File "/usr/lib/python3.6/unittest/__init__.py", line 64, in <module>
    from .main import TestProgram, main
  ...
  File "/usr/lib/python3.6/unittest/signals.py", line 1, in <module>
    import signal
  File "/home/steve/src/foo/signal.py", line 1, in <module>
    import talib
  File "/home/steve/src/foo/.venv/lib/python3.6/site-packages/talib/__init__.py", line 43, in <module>
    from ._ta_lib import (
  File "__init__.pxd", line 163, in init talib._ta_lib
AttributeError: module 'numpy' has no attribute 'dtype'

如果将本地文件重命名为其他文件,则不会发生上述错误

代码语言:javascript
复制
$ mv signal.py signal_foo.py
$ python strategy.py 
$ echo $?
0

问题:

  • 除了要求我选择一个唯一的文件名之外,还有其他方法解决这个问题吗?
  • 如果是这样的话,我如何确保我的文件名不会在未来冲突,要求我选择另一个唯一的文件名?

备注:

我在virtualenv中运行,并且使用python-3.6.5

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-08 17:41:01

这种行为是根据模块搜索路径进行的。

当导入名为垃圾邮件的模块时,解释器首先搜索具有该名称的内置模块。如果找不到,则在变量spam.py提供的目录列表中搜索名为sys.path的文件。从以下位置初始化sys.path: 包含输入脚本(或当前目录)的目录。PYTHONPATH (与shell变量路径具有相同语法的目录名称列表)。与安装相关的默认设置。 初始化后,Python程序可以修改sys.path。包含正在运行的脚本的目录位于搜索路径的开头,位于标准库路径的前面。这意味着将加载该目录中的脚本,而不是库目录中同名的模块。

因此,一个答案是您可以操作sys.path,将您想要首先使用的目录放在列表中。但是,这并不能真正解决你的长期问题。

更好的方法是将您自己的代码组织到套餐中。

包是使用“虚线模块名称”构造Python模块命名空间的一种方法。例如,模块名A.B在一个名为A的包中指定一个名为B的子模块。

如果将signal.py放入包myPkg中,则可以使用以下方法具体导入它;

代码语言:javascript
复制
import myPkg.signal

如果将两个信号模块导入到相同的脚本中,这可能仍不能解决所有问题。但是,您可以在导入上分配一个新的模块名;

代码语言:javascript
复制
import myPkg.signal as mySignal

在工作目录中创建此结构;

代码语言:javascript
复制
/path/to/myPkg/
    __init__.py
    signal.py
    tests/
        __init__.py
        test.py

test.py中放置这样的东西

代码语言:javascript
复制
print '1'
import signal

print '2'
import myPkg.signal as ms

现在,要运行此操作,您需要将myPkg添加到PYTHONPATH中,或者在解释器中进行快速检查。注意:cd指向myPkg的父目录,而不是myPkg

代码语言:javascript
复制
cd /path/to
python
>>> import sys
>>> sys.path
['', '/usr/lib/python27.zip', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-cygwin', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/lib/python2.7/site-packages']
>>> sys.path.append('./myPkg')
>>> import myPkg.tests.test
1
2
>>> quit()
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51752353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档