有人能为我提供一个导入整个模块目录的好方法吗? 我有这样的结构:
/Foo
bar.py
spam.py
eggs.py
我尝试通过添加__init__.py
并执行from Foo import *
将其转换为包,但它没有按照我希望的方式运行。
答案 0 :(得分:341)
列出当前文件夹中的所有python(.py
)文件,并将它们作为__all__
__init__.py
变量放入
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
答案 1 :(得分:123)
将__all__
变量添加到__init__.py
包含:
__all__ = ["bar", "spam", "eggs"]
答案 2 :(得分:42)
更新:今天您可能想要使用importlib
。
通过添加__init__.py
使Foo目录成为包。在__init__.py
添加:
import bar
import eggs
import spam
既然你想要它是动态的(这可能是也可能不是一个好主意),列出所有包含list dir的py文件并用以下内容导入它们:
import os
for module in os.listdir(os.path.dirname(__file__)):
if module == '__init__.py' or module[-3:] != '.py':
continue
__import__(module[:-3], locals(), globals())
del module
然后,从您的代码中执行此操作:
import Foo
您现在可以使用
访问模块Foo.bar
Foo.eggs
Foo.spam
等。来自Foo import *不是一个好主意,原因有多种,包括名称冲突以及难以分析代码。
答案 3 :(得分:34)
扩展Mihail的答案,我相信非hackish方式(如,不直接处理文件路径)如下:
__init__.py
Foo/
文件
import pkgutil
import sys
def load_all_modules_from_dir(dirname):
for importer, package_name, _ in pkgutil.iter_modules([dirname]):
full_package_name = '%s.%s' % (dirname, package_name)
if full_package_name not in sys.modules:
module = importer.find_module(package_name
).load_module(full_package_name)
print module
load_all_modules_from_dir('Foo')
你会得到:
<module 'Foo.bar' from '/home/.../Foo/bar.pyc'>
<module 'Foo.spam' from '/home/.../Foo/spam.pyc'>
答案 4 :(得分:20)
对于那些无法让他们工作的新手需要他们的双手。
创建一个文件夹/ home / el / foo并在/ home / el / foo下创建一个文件main.py
。将此代码放在那里:
from hellokitty import *
spam.spamfunc()
ham.hamfunc()
制作目录/home/el/foo/hellokitty
在__init__.py
下创建一个文件/home/el/foo/hellokitty
并将此代码放在那里:
__all__ = ["spam", "ham"]
制作两个python文件:spam.py
下的ham.py
和/home/el/foo/hellokitty
在spam.py中定义一个函数:
def spamfunc():
print "Spammity spam"
在ham.py中定义一个函数:
def hamfunc():
print "Upgrade from baloney"
运行它:
el@apollo:/home/el/foo$ python main.py
spammity spam
Upgrade from baloney
答案 5 :(得分:16)
我自己厌倦了这个问题,所以我写了一个名为automodinit的软件包来修复它。你可以从http://pypi.python.org/pypi/automodinit/获得它。
用法是这样的:
automodinit
包添加到setup.py
依赖项中。__all__ = ["I will get rewritten"] # Don't modify the line above, or this line! import automodinit automodinit.automodinit(__name__, __file__, globals()) del automodinit # Anything else you want can go after here, it won't get modified.
就是这样!从现在开始,导入模块将__all__设置为 模块中的.py [co]文件列表,也将导入每个文件 这些文件就好像你输入了一样:
for x in __all__: import x
因此,“来自M import *”的效果完全匹配“import M”。
automodinit
很高兴从ZIP档案中运行,因此可以保存ZIP。
尼尔
答案 6 :(得分:7)
我知道我正在更新一篇相当古老的帖子,我尝试使用automodinit
,但发现它的设置过程已经被python3破坏了。所以,根据Luca的回答,我想出了一个更简单的答案 - 这可能不适用于.zip - 这个问题,所以我想我应该在这里分享一下:
来自__init__.py
的{{1}}模块:
yourpackage
并在#!/usr/bin/env python
import os, pkgutil
__all__ = list(module for _, module, _ in pkgutil.iter_modules([os.path.dirname(__file__)]))
下面的另一个包中:
yourpackage
然后,您将已加载包中的所有模块,如果您编写新模块,它也将自动导入。当然,谨慎使用这种事物,有很大的权力,这是很重要的责任。
答案 7 :(得分:5)
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
for imp, module, ispackage in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
__import__(module)
答案 8 :(得分:5)
我也遇到过这个问题,这是我的解决方案:
import os
def loadImports(path):
files = os.listdir(path)
imps = []
for i in range(len(files)):
name = files[i].split('.')
if len(name) > 1:
if name[1] == 'py' and name[0] != '__init__':
name = name[0]
imps.append(name)
file = open(path+'__init__.py','w')
toWrite = '__all__ = '+str(imps)
file.write(toWrite)
file.close()
此函数创建一个名为__init__.py
的文件(在提供的文件夹中),该文件包含一个__all__
变量,用于保存文件夹中的每个模块。
例如,我有一个名为Test
的文件夹
其中包含:
Foo.py
Bar.py
所以在脚本中我想要导入模块,我会写:
loadImports('Test/')
from Test import *
这将导入Test
中的所有内容,__init__.py
中的Test
文件现在将包含:
__all__ = ['Foo','Bar']
答案 9 :(得分:4)
Anurag Uniyal answer并提出改进建议!
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import os
import glob
all_list = list()
for f in glob.glob(os.path.dirname(__file__)+"/*.py"):
if os.path.isfile(f) and not os.path.basename(f).startswith('_'):
all_list.append(os.path.basename(f)[:-3])
__all__ = all_list
答案 10 :(得分:4)
Anurag的例子有几处更正:
import os, glob
modules = glob.glob(os.path.join(os.path.dirname(__file__), "*.py"))
__all__ = [os.path.basename(f)[:-3] for f in modules if not f.endswith("__init__.py")]
答案 11 :(得分:3)
看到您的__init__.py
定义__all__
。 modules - packages doc说
需要
__init__.py
个文件才能使Python将目录视为包含包;这样做是为了防止具有通用名称的目录(例如字符串)无意中隐藏稍后在模块搜索路径上发生的有效模块。在最简单的情况下,__init__.py
可以只是一个空文件,但它也可以执行包的初始化代码或设置__all__
变量,稍后将对此进行描述。...
唯一的解决方案是让包作者提供包的显式索引。 import语句使用以下约定:如果包的
__init__.py
代码定义了名为__all__
的列表,则它将被视为遇到包import *时应导入的模块名称列表。在发布新版本的软件包时,由软件包作者决定是否保持此列表的最新状态。如果包装作者没有看到从包装中导入*的用途,他们也可能决定不支持它。例如,文件sounds/effects/__init__.py
可以包含以下代码:
__all__ = ["echo", "surround", "reverse"]
这意味着
from sound.effects import *
会导入声音包的三个命名子模块。
答案 12 :(得分:3)
这是迄今为止我发现的最佳方式:
from os.path import dirname, join, isdir, abspath, basename
from glob import glob
pwd = dirname(__file__)
for x in glob(join(pwd, '*.py')):
if not x.startswith('__'):
__import__(basename(x)[:-3], globals(), locals())
答案 13 :(得分:1)
我为此创建了一个模块,它不依赖于__init__.py
(或任何其他辅助文件),只让我输入以下两行:
import importdir
importdir.do("Foo", globals())
答案 14 :(得分:1)
从标准库中查看pkgutil模块。只要目录中有__init__.py
文件,它就可以让您完全按照自己的意愿行事。 <{1}}文件可以为空。
答案 15 :(得分:1)
唯一需要添加的是importlib
from importlib import import_module
from pathlib import Path
__all__ = [
import_module(f".{f.stem}", __package__)
for f in Path(__file__).parent.glob("*.py")
if "__" not in f.stem
]
del import_module, Path
答案 16 :(得分:1)
我想补充 Anurag Uniyal 的答案。 你可以让它变得更简单,去掉很多导入。 __init__.py 文件的内容:
public class NvidiaRoot
{
public object categories { get; set; }
public List<Filter> filters { get; set; }
public object filterGroups { get; set; }
public object search { get; set; }
public string version { get; set; }
public List<Sort> sort { get; set; }
public Pagination pagination { get; set; }
public SearchedProducts searchedProducts { get; set; }
public Disclaimer disclaimer { get; set; }
}
public class FilterValue
{
public string dispValue { get; set; }
public object dispValueDesription { get; set; }
public object groupType { get; set; }
public int units { get; set; }
public bool @checked { get; set; }
public object imageURL { get; set; }
public bool isValidate { get; set; }
}
public class Filter
{
public string displayName { get; set; }
public string filterField { get; set; }
public string displayMaxValues { get; set; }
public string fieldType { get; set; }
public int? selectedMinRangeVal { get; set; }
public int? selectedMaxRangeVal { get; set; }
public int? defaultMinRangeVal { get; set; }
public int? defaultMaxRangeVal { get; set; }
public string unitsOfMeasure { get; set; }
public bool @checked { get; set; }
public object units { get; set; }
public List<FilterValue> filterValues { get; set; }
public string dataType { get; set; }
public bool showCount { get; set; }
public int filterDisplayOrder { get; set; }
}
public class Sort
{
public string displayName { get; set; }
public string value { get; set; }
public bool selected { get; set; }
}
public class Pagination
{
public int page { get; set; }
public int limit { get; set; }
public int totalRecords { get; set; }
public bool featuredProductIncludedInCount { get; set; }
}
public class Retailer
{
public int productId { get; set; }
public string productTitle { get; set; }
public string logoUrl { get; set; }
public bool isAvailable { get; set; }
public string salePrice { get; set; }
public string directPurchaseLink { get; set; }
public string purchaseLink { get; set; }
public bool hasOffer { get; set; }
public object offerText { get; set; }
public string partnerId { get; set; }
public string storeId { get; set; }
public string upc { get; set; }
public string sku { get; set; }
public int stock { get; set; }
public string retailerName { get; set; }
public int type { get; set; }
}
public class ProductInfo
{
public string name { get; set; }
public string value { get; set; }
}
public class CompareProductInfo
{
public string name { get; set; }
public string value { get; set; }
}
public class FeaturedProduct
{
public string displayName { get; set; }
public int totalCount { get; set; }
public int productID { get; set; }
public string imageURL { get; set; }
public string productTitle { get; set; }
public string digitialRiverID { get; set; }
public string productSKU { get; set; }
public string productUPC { get; set; }
public string productUPCOriginal { get; set; }
public string productPrice { get; set; }
public bool productAvailable { get; set; }
public object productRating { get; set; }
public object customerReviewCount { get; set; }
public bool isFounderEdition { get; set; }
public bool isFeaturedProduct { get; set; }
public bool certified { get; set; }
public string manufacturer { get; set; }
public string locale { get; set; }
public bool isFeaturedProdcutFoundInSecondSearch { get; set; }
public string category { get; set; }
public string gpu { get; set; }
public string purchaseOption { get; set; }
public string prdStatus { get; set; }
public object minShipDays { get; set; }
public object maxShipDays { get; set; }
public object shipInfo { get; set; }
public bool isOffer { get; set; }
public string offerText { get; set; }
public List<Retailer> retailers { get; set; }
public List<ProductInfo> productInfo { get; set; }
public List<CompareProductInfo> compareProductInfo { get; set; }
}
public class ProductDetail
{
public string displayName { get; set; }
public int totalCount { get; set; }
public int productID { get; set; }
public string imageURL { get; set; }
public string productTitle { get; set; }
public string digitialRiverID { get; set; }
public string productSKU { get; set; }
public string productUPC { get; set; }
public string productUPCOriginal { get; set; }
public string productPrice { get; set; }
public bool productAvailable { get; set; }
public object productRating { get; set; }
public object customerReviewCount { get; set; }
public bool isFounderEdition { get; set; }
public bool isFeaturedProduct { get; set; }
public bool certified { get; set; }
public string manufacturer { get; set; }
public string locale { get; set; }
public bool isFeaturedProdcutFoundInSecondSearch { get; set; }
public string category { get; set; }
public string gpu { get; set; }
public string purchaseOption { get; set; }
public string prdStatus { get; set; }
public object minShipDays { get; set; }
public object maxShipDays { get; set; }
public object shipInfo { get; set; }
public bool isOffer { get; set; }
public string offerText { get; set; }
public List<Retailer> retailers { get; set; }
public List<ProductInfo> productInfo { get; set; }
public List<CompareProductInfo> compareProductInfo { get; set; }
}
public class SearchedProducts
{
public int totalProducts { get; set; }
public bool featuredProductIncludedInCount { get; set; }
public bool featuredProductsFlag { get; set; }
public FeaturedProduct featuredProduct { get; set; }
public List<ProductDetail> productDetails { get; set; }
public List<object> suggestedProductDetails { get; set; }
}
public class Disclaimer
{
public string text { get; set; }
}
答案 17 :(得分:0)
只需按importlib导入它们,然后将其添加到__all__
(add
操作是可选的),然后递归到__init__.py
包中。
/Foo
bar.py
spam.py
eggs.py
__init__.py
# __init__.py
import os
import importlib
pyfile_extes = ['py', ]
__all__ = [importlib.import_module('.%s' % filename, __package__) for filename in [os.path.splitext(i)[0] for i in os.listdir(os.path.dirname(__file__)) if os.path.splitext(i)[1] in pyfile_extes] if not filename.startswith('__')]
del os, importlib, pyfile_extes
答案 18 :(得分:0)
当from . import *
不够好时,这是对answer by ted的改进。具体来说,这种方法不需要使用__all__
。
"""Import all modules that exist in the current directory."""
# Ref https://stackoverflow.com/a/60861023/
from importlib import import_module
from pathlib import Path
for f in Path(__file__).parent.glob("*.py"):
module_name = f.stem
if (not module_name.startswith("_")) and (module_name not in globals()):
import_module(f".{module_name}", __package__)
del f, module_name
del import_module, Path
请注意,module_name not in globals()
旨在避免重新导入模块(如果已导入),因为这可能会导致循环导入。
答案 19 :(得分:-1)
我有一个嵌套的目录结构,即我在包含 python 模块的主目录中有多个目录。
我将以下脚本添加到我的 __init__.py
文件中以导入所有模块
import glob, re, os
module_parent_directory = "path/to/the/directory/containing/__init__.py/file"
owd = os.getcwd()
if not owd.endswith(module_parent_directory): os.chdir(module_parent_directory)
module_paths = glob.glob("**/*.py", recursive = True)
for module_path in module_paths:
if not re.match( ".*__init__.py$", module_path):
import_path = module_path[:-3]
import_path = import_path.replace("/", ".")
exec(f"from .{import_path} import *")
os.chdir(owd)
可能不是实现这一目标的最佳方式,但我无法让其他任何事情对我有用。