在 python setup.py data_files 中包含整个目录
Include entire directory in python setup.py data_files
设置的 data_files 参数采用以下格式输入:
setup(...
data_files = [(target_directory, [list of files to be put there])]
....)
有没有一种方法可以让我指定整个数据目录,这样我就不必单独命名每个文件并在我更改项目中的实现时更新它?
我尝试使用 os.listdir()
,但我不知道如何使用相对路径,我无法使用 os.getcwd()
或 os.realpath(__file__)
,因为它们不正确指向我的存储库根目录。
I don't know how to do that with relative paths
需要先获取目录的路径,所以...
假设你有这个目录结构:
cur_directory
|- setup.py
|- inner_dir
|- file2.py
要获取当前文件的目录(在本例中为 setup.py),请使用:
cur_directory_path = os.path.abspath(os.path.dirname(__file__))
然后,要获取相对于current_directory
的目录路径,只需加入一些其他目录即可,例如:
inner_dir_path = os.path.join(cur_directory_path, 'inner_dir')
如果要上移目录,只需使用“..
”,例如:
parent_dir_path = os.path.join(current_directory, '..')
一旦你有了那条路,你就可以os.listdir
为了完整性:
如果你想要文件的路径,在本例中是相对于 setup.py
的“file2.py
”,你可以这样做:
file2_path = os.path.join(cur_directory_path, 'inner_dir', 'file2.py')
import glob
for filename in glob.iglob('inner_dir/**/*', recursive=True):
print (filename)
这样做,您将直接获得相对于当前目录的文件列表。
karelv 的想法是正确的,但更直接地回答所述问题:
from glob import glob
setup(
#...
data_files = [
('target_directory_1', glob('source_dir/*')), # files in source_dir only - not recursive
('target_directory_2', glob('nested_source_dir/**/*', recursive=True)), # includes sub-folders - recursive
# etc...
],
#...
)
我 运行 遇到包含嵌套子目录的目录的相同问题。 glob 解决方案不起作用,因为它们会在列表中包含目录,安装程序会爆炸,并且在我排除匹配目录的情况下,它仍然将它们全部转储到同一目录中,这不是我想要的, 任何一个。我最终还是回到了 os.walk()
:
def generate_data_files():
data_files = []
data_dirs = ('data', 'plugins')
for path, dirs, files in chain.from_iterable(os.walk(data_dir) for data_dir in data_dirs):
install_dir = os.path.join(sys.prefix, 'share/<my-app>/' + path)
list_entry = (install_dir, [os.path.join(path, f) for f in files if not f.startswith('.')])
data_files.append(list_entry)
return data_files
然后在setup()
块中设置data_files=generate_data_files()
。
对于嵌套的子目录,如果你想保留原来的目录结构,你可以使用os.walk()
,如另一个答案中所建议的。
但是,更简单的解决方案是使用扩展 setuptools
的 pbr
库。有关如何使用它安装整个目录结构的文档,请参阅此处:
设置的 data_files 参数采用以下格式输入:
setup(...
data_files = [(target_directory, [list of files to be put there])]
....)
有没有一种方法可以让我指定整个数据目录,这样我就不必单独命名每个文件并在我更改项目中的实现时更新它?
我尝试使用 os.listdir()
,但我不知道如何使用相对路径,我无法使用 os.getcwd()
或 os.realpath(__file__)
,因为它们不正确指向我的存储库根目录。
I don't know how to do that with relative paths
需要先获取目录的路径,所以...
假设你有这个目录结构:
cur_directory
|- setup.py
|- inner_dir
|- file2.py
要获取当前文件的目录(在本例中为 setup.py),请使用:
cur_directory_path = os.path.abspath(os.path.dirname(__file__))
然后,要获取相对于current_directory
的目录路径,只需加入一些其他目录即可,例如:
inner_dir_path = os.path.join(cur_directory_path, 'inner_dir')
如果要上移目录,只需使用“..
”,例如:
parent_dir_path = os.path.join(current_directory, '..')
一旦你有了那条路,你就可以os.listdir
为了完整性:
如果你想要文件的路径,在本例中是相对于 setup.py
的“file2.py
”,你可以这样做:
file2_path = os.path.join(cur_directory_path, 'inner_dir', 'file2.py')
import glob
for filename in glob.iglob('inner_dir/**/*', recursive=True):
print (filename)
这样做,您将直接获得相对于当前目录的文件列表。
karelv 的想法是正确的,但更直接地回答所述问题:
from glob import glob
setup(
#...
data_files = [
('target_directory_1', glob('source_dir/*')), # files in source_dir only - not recursive
('target_directory_2', glob('nested_source_dir/**/*', recursive=True)), # includes sub-folders - recursive
# etc...
],
#...
)
我 运行 遇到包含嵌套子目录的目录的相同问题。 glob 解决方案不起作用,因为它们会在列表中包含目录,安装程序会爆炸,并且在我排除匹配目录的情况下,它仍然将它们全部转储到同一目录中,这不是我想要的, 任何一个。我最终还是回到了 os.walk()
:
def generate_data_files():
data_files = []
data_dirs = ('data', 'plugins')
for path, dirs, files in chain.from_iterable(os.walk(data_dir) for data_dir in data_dirs):
install_dir = os.path.join(sys.prefix, 'share/<my-app>/' + path)
list_entry = (install_dir, [os.path.join(path, f) for f in files if not f.startswith('.')])
data_files.append(list_entry)
return data_files
然后在setup()
块中设置data_files=generate_data_files()
。
对于嵌套的子目录,如果你想保留原来的目录结构,你可以使用os.walk()
,如另一个答案中所建议的。
但是,更简单的解决方案是使用扩展 setuptools
的 pbr
库。有关如何使用它安装整个目录结构的文档,请参阅此处: