在Python中实现“from。import *”的最佳方式是什么?
我正在使用Django,我喜欢将我的模型,视图和测试分离到子目录中。在Python中实现“from。import *”的最佳方式是什么?
但是,这意味着我需要在导入该目录中每个模块的每个子目录中保留一个__init__.py
。
我宁愿只是把一些呼叫,说:
from some_library import import_everything
import_everything()
这将对作为遍历当前目录相同的效果,并在该目录中导入所有的.py文件。
什么是最好/最简单的方法来实现这个?
这里是什么我的Django应用程序目录(基本)的样子:
some_django_app/
models/
__init__.py
create.py
read.py
update.py
delete.py
views/
__init__.py
create.py
read.py
update.py
delete.py
forms/
__init__.py
create.py
update.py
tests/
__init__.py
create.py
read.py
update.py
delete.py
所以,你可以看到,做一个“适当”的Django应用程序,我所有的初始化 .py文件需进口每个目录中的所有其他.py文件。我宁愿在那里有一些简单的样板。
使用synthesizerpatel's answer给出的信息,你可以实现import_everything
这样:
import os
import sys
def import_everything(path):
# Insert near the beginning so path will be the item removed with sys.path.remove(path) below
# (The case when sys.path[0] == path works fine too).
# Do not insert at index 0 since sys.path[0] may have a special meaning
sys.path.insert(1,path)
for filename in os.listdir(path):
if filename.endswith('.py'):
modname = filename.replace('.py', '')
module = __import__(modname, fromlist = [True])
attrs = getattr(module, '__all__',
(attr for attr in dir(module) if not attr.startswith('_')))
for attr in attrs:
# print('Adding {a}'.format(a = attr))
globals()[attr] = getattr(module, attr)
sys.path.remove(path)
,并且可以使用这样的:
print(globals().keys())
# ['import_everything', '__builtins__', '__file__', '__package__', 'sys', '__name__', 'os', '__doc__']
import_everything(os.path.expanduser('~/test'))
print(globals().keys())
# ['hashlib', 'pythonrc', 'import_everything', '__builtins__', 'get_input', '__file__', '__package__', 'sys', 'mp', 'time', 'home', '__name__', 'main', 'os', '__doc__', 'user']
在您app/models/__init__.py
加上这些行:
from app.models.create import *
from app.models.read import *
from app.models.update import *
from app.models.delete import *
这将是您最好的选择简洁和可读性。 from app.models import *
现在将加载其他每个文件中的所有类/ etc。同样,from app.models import foo
将加载foo
,无论它定义在哪个文件中。
是的,这正是我现在所做的,我觉得它很累。对于每个新的测试用例或表单,我都需要不断更新__init__.py。对于大多数情况(模型,视图),这是可以的,但是对于测试来说这是最糟糕的,因为我喜欢在那里有很多文件,而不是一个巨大的tests.py,__init__.py在其中有很多行。 – slacy 2012-01-30 20:10:27
@slacy这听起来像是一种糟糕的组织方式。为什么不把测试分成逻辑分组 - model_tests.py,view_tests.py等等? (或其他一些对该应用有意义的分组,例如user_tests,guest_tests或其他) – Izkata 2012-01-30 21:04:34
是的,实际上,我们确实有model_tests.py和view_tests,但即使是那些文件也会得到> 1000行,我们最终将它们分开。 :) – slacy 2012-01-30 22:28:55
您可以添加示例目录布局吗? – Cameron 2012-01-30 18:49:39
更新为包含目录布局。 – slacy 2012-01-30 19:01:56
请注意'来自。 import *'通常是一个坏主意,因为名字空间可能会在您不知情的情况下被覆盖。请参阅[有关该主题的文档](http://docs.python.org/howto/doanddont.html#from-module-import) – 2012-01-30 19:42:31