我们都被告知使用from module import *是一个坏主意.但是,有没有办法导入使用通配符的内容的子集module?
例如:
module.py:
MODULE_VAR1 = "hello"
MODULE_VAR2 = "world"
MODULE_VAR3 = "The"
MODULE_VAR4 = "quick"
MODULE_VAR5 = "brown"
...
MODULE_VAR10 = "lazy"
MODULE_VAR11 = "dog!"
MODULE_VAR12 = "Now"
MODULE_VAR13 = "is"
...
MODULE_VAR98 = "Thats"
MODULE_VAR99 = "all"
MODULE_VAR100 = "folks!"
def abs():
print "Absolutely useful function: %s" % MODULE_VAR1
Run Code Online (Sandbox Code Playgroud)
显然我们不想使用,from module import *因为我们要覆盖这个abs功能.但是假设我们DID希望所有MODULE_VAR*变量都可以在本地访问.
简单地推杆from module import MODULE_VAR*不起作用.有没有办法实现这个目标?
我使用了100个变量作为说明,因为from module import MODULE_VAR1, MODULE_VAR2, …
在阅读fastapi的源代码时,这一行让我很模糊:
from starlette.testclient import TestClient as TestClient
Run Code Online (Sandbox Code Playgroud)
为什么不只是:from starlette.testclient import TestClient?
我知道这import *很糟糕,但是当我觉得懒得键入或记住进口时,我有时会用它来快速进行原型设计
我正在尝试以下代码:
from OpenGL.GL import *
shaders.doSomething()
Run Code Online (Sandbox Code Playgroud)
它会导致错误:`NameError:全局名称'着色器'未定义'
如果我更改导入:
from OpenGL.GL import *
from OpenGL.GL import shaders
shaders.doSomething()
Run Code Online (Sandbox Code Playgroud)
错误消失了.为什么不*包括shaders?
我正在编写一个简单的Python库,其中我有几个以下划线开头的"私有"函数:
def _a():
pass
def _b():
pass
def public_interface_call():
_a()
_b()
Run Code Online (Sandbox Code Playgroud)
这样我的库用户可以简单地做,from MyLib.Module import *并且他们的命名空间不会与实现细节混杂在一起.
然而,我也在编写单元测试,我很乐意分别测试这些函数,简单地导入我模块中的所有符号都非常方便.目前我在做,from Mylib.Module import _a _b public_interface_call但我想知道是否有更好/更快/更清洁的方式来实现我想要的?
由于导入问题,我已按照此处显示的步骤将我的 Python 项目安装为可编辑pip包。基本上这需要pip install -e .从我的项目根目录运行。项目名称为“myproject”,setup.py配置如下:
from setuptools import setup, find_packages
setup(name='myproject', version='1.0', packages=find_packages())
Run Code Online (Sandbox Code Playgroud)
项目结构是这样的:
.
??? myproject
? ??? core
? ? ??? core.py
? ? ??? __init__.py
? ??? tests
? ??? __init__.py
? ??? test_one.py
??? setup.py
??? env
??? ...
Run Code Online (Sandbox Code Playgroud)
随着venv启动,我得到下面的输出:
(env) [root@localhost /]$ python -V
Python 3.6.3
(env) [root@localhost /]$ pip -V
pip 9.0.1 from /myproject/venv/lib64/python3.6/site-packages (python 3.6)
Run Code Online (Sandbox Code Playgroud)
但是,在运行解释会话时,我会遇到以下情况:
(env) [root@localhost /]$ python
>>> import …Run Code Online (Sandbox Code Playgroud) 我想创建一个像NumPy一样工作的Python模块。这些方法不仅是模块源中树的叶子中的子模块。有一个包含许多我可以直接调用的方法的根模块,还有一些子模块。问题是根方法必须在某处定义。我当时想拥有一个目录结构:
module/
__init__.py
core.py
stuff1.py
submodule/
__init__.py
stuff2.py
stuff3.py
Run Code Online (Sandbox Code Playgroud)
现在,我希望将“ core”内部的所有内容导入“ module”命名空间,就好像它是一个module.py文件,而core.py的内容都在此module.py内部。问题在于模块是目录而不是文件,那么如何定义应该位于模块根目录中的这些方法?
我尝试将“ from core import *”放在init .py中,但这没有用。(编辑:实际上是。)
我是否应该在“ module.py”文件以及模块目录中包含核心方法?我不知道这是否可行,但是看起来很尴尬。
当我尝试使用pyplot时matplotlib:
import matplotlib
print matplotlib.pyplot # just checking
Run Code Online (Sandbox Code Playgroud)
它给了我 AttributeError: 'module' object has no attribute 'pyplot'
它可以通过以下方式解决:
import matplotlib.pyplot
Run Code Online (Sandbox Code Playgroud)
但我真的很困惑的是,
import numpy
print numpy.random
Run Code Online (Sandbox Code Playgroud)
给我 <module 'numpy.random' from '/Applications/Canopy.app/appdata/canopy-1.0.3.1262.macosx-x86_64/Canopy.app/Contents/lib/python2.7/site-packages/numpy/random/__init__.pyc'>
两种情况有什么区别?pyplot在第一个例子中不能被调用,但是random在第二个例子中.我认为它与某种包和模块有关.但我不是蟒蛇的专业人士,因此要求回答.
这是一个概念性问题,而不是一个实际问题,我想向广大互联网群众寻求反馈。
我们都知道导入的模块最终位于该模块的命名空间中:
# Module a:
import b
__all__ = ['f']
f = lambda: None
Run Code Online (Sandbox Code Playgroud)
这允许你这样做:
import a
a.b # <- Valid attribute
Run Code Online (Sandbox Code Playgroud)
有时这很好,但大多数导入都是模块提供的功能的副作用。在上面的示例中,我并不是b要向a.
为了抵消这个问题,我们可以这样做:
import b as _b
Run Code Online (Sandbox Code Playgroud)
这将导入标记为私有。但我找不到任何地方描述的这种做法,PEP8 也没有讨论使用别名将导入标记为私有。所以我认为这不是常见的做法。但从某个角度来看,我想说它在语义上肯定更清晰,因为它清理了模块的暴露部分,只留下您实际想要暴露的相关接口。使用具有自动完成功能的 IDE 可以使建议列表变得更加精简。
我的问题归结为您是否见过这种模式的使用?它有名字吗?什么论据会反对使用它?
我没有成功使用__all__隐藏b导入的功能。我正在使用 PyCharm,但没有看到自动完成列表发生变化。
例如,从某个模块我可以执行以下操作:
import a
Run Code Online (Sandbox Code Playgroud)
自动完成框显示b和f。
我正在创建一个聊天main.py机器人,commands.py它有 2 个主要文件,它运行机器人并包含机器人识别的命令。我试图从中获取函数名称commands.py,以便在main.py. 例如:
命令.py
def add():
pass
def delete():
pass
def change():
pass
Run Code Online (Sandbox Code Playgroud)
基本上,我希望能够存储在变量commands = ['add', 'delete', 'change']或类似的东西中。我对装饰器没有任何经验,但这可能是使用它的好时机吗?能够使用装饰器注册命令?我愿意接受任何建议,谢谢!
我有一个以下形式的python包:
package
??? __init__.py
??? module_1.py
??? module_2.py
Run Code Online (Sandbox Code Playgroud)
在 __init__.py 里面我有:
package
??? __init__.py
??? module_1.py
??? module_2.py
Run Code Online (Sandbox Code Playgroud)
Module_1 是:
__all__ = ["module_1", "module_2"]
Run Code Online (Sandbox Code Playgroud)
Module_2 是:
__all__ = ["foo"]
def foo(): pass
Run Code Online (Sandbox Code Playgroud)
从文档中我认为以下代码将导入foo和Bar:
__all__ = ["Bar"]
class Bar: pass
Run Code Online (Sandbox Code Playgroud)
但是,当我运行pk.foo()它时会引发错误:(AttributeError: module 'package' has no attribute 'foo'对于 Bar 也是如此)。
感谢这个答案,我知道要获得所需的行为,我可以将 __init__.py 更改为:
import package as pk
Run Code Online (Sandbox Code Playgroud)
以上工作。
但是,我不明白 文档。线路:
如果一个包的 __init__.py 代码定义了一个名为 __all__ 的列表,它被认为是遇到 from package import …
python ×10
python-3.x ×3
decorator ×1
import ×1
matplotlib ×1
module ×1
mypy ×1
numpy ×1
package ×1
pip ×1
python-2.7 ×1
python-venv ×1
wildcard ×1