我们正在使用一个代码存储库,它部署在Windows和Linux上 - 有时在不同的目录上.项目中的一个模块应该如何引用项目中的一个非Python资源(CSV文件等)?
如果我们做类似的事情:
thefile=open('test.csv')
Run Code Online (Sandbox Code Playgroud)
要么:
thefile=open('../somedirectory/test.csv')
Run Code Online (Sandbox Code Playgroud)
仅当脚本从一个特定目录或目录的子集运行时,它才会起作用.
我想做的是:
path=getBasePathOfProject()+'/somedirectory/test.csv'
thefile=open(path)
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?可能吗?
我正在编写一个包含需要在./data/子目录中打开数据文件的模块的python包.现在我有了硬编码到我的类和函数中的文件的路径.我想编写更强大的代码,可以访问子目录,无论它在用户系统上的安装位置如何.
我尝试了各种各样的方法,但到目前为止我没有运气.似乎大多数"当前目录"命令都返回系统的python解释器的目录,而不是模块的目录.
这似乎应该是一个微不足道的常见问题.但我似乎无法弄明白.部分问题是我的数据文件不是.py文件,所以我不能使用导入功能等.
有什么建议?
现在我的包目录看起来像:
/
__init__.py
module1.py
module2.py
data/
data.txt
Run Code Online (Sandbox Code Playgroud)
我试图访问data.txt距离module*.py
谢谢!
这是我删除的非代码内容的精简版setup.py脚本:
#!/usr/bin/env python
from distutils.core import setup
from whyteboard.misc import meta
setup(
name = 'Whyteboard',
version = meta.version,
packages = ['whyteboard', 'whyteboard.gui', 'whyteboard.lib', 'whyteboard.lib.pubsub',
'whyteboard.lib.pubsub.core', 'whyteboard.lib.pubsub.utils', 'whyteboard.misc'],
py_modules = ['whyteboard'],
scripts = ['whyteboard.py'],
)
Run Code Online (Sandbox Code Playgroud)
MANIFEST.in:
include *.txt
include whyteboard-help/*.*
recursive-include locale *.mo
recursive-include images *.png
Run Code Online (Sandbox Code Playgroud)
当我运行"python setup.py install sdist"时,我得到一个很好的.tar.gz,带有"whyteboard-0.41"根文件夹,里面有我的locale/images /和whyteboard-help/folders.这也有我的whyteboard.py脚本,它从whyteboard源包中启动我的程序.
所以:
whyteboard/
??? locale/
??? images
??? whyteboard-help/
??? whyteboard/
? ??? __init__.py
? ??? other packages etc
??? whyteboard.py
??? README
??? setup.py
??? CHANGELOG
Run Code Online (Sandbox Code Playgroud)
这反映了我的程序的来源,一切应该是怎样的,并且是正确的.
但是,当我运行"python setup.py install"时,我的数据文件都没有写入 …
包含静态文件是不可能的!我尝试了我在教程和文档中找到的所有内容,但都是徒劳的......
我想要包含./static/data.txt,还有我的代码:
# setup.py
import os,glob
from setuptools import setup,find_packages
setup(
name = "PotatoProject",
version = "0.1.1",
author = "Master Splinter",
author_email = "splinter@initech.com",
description = ("The potatoproject!"),
url = 'http://www.google.com',
license = "BSD",
# adding packages
packages=find_packages('src'),
package_dir = {'':'src'},
# trying to add files...
include_package_data = True,
package_data = {
'': ['*.txt'],
'': ['static/*.txt'],
'static': ['*.txt'],
},
scripts=['src/startPotato'],
classifiers=[
"Development Status :: 3 - Alpha",
"Topic :: Utilities",
"License :: OSI Approved :: BSD License",
],
)
Run Code Online (Sandbox Code Playgroud)
文件系统: …
假设你有一个包含的模块
myfile = open('test.txt', 'r')
Run Code Online (Sandbox Code Playgroud)
'test.txt'文件位于同一个文件夹中.如果您将运行该模块,该文件将成功打开.现在假设您从另一个文件夹中导入该模块.不会在与该代码所在的模块相同的文件夹中搜索该文件.那么如何让模块首先在同一个文件夹中搜索相对路径的文件呢?使用" __file__"或" os.getcwd()" 有各种解决方案,但我希望有一种更简洁的方法,就像传递给open()或file()的字符串中的相同特殊字符一样.
我有一个Python模块,它使用模块目录的子目录中的一些资源.在搜索堆栈溢出并找到相关答案后,我设法通过使用类似的东西将模块引导到资源
import os
os.path.join(os.path.dirname(__file__), 'fonts/myfont.ttf')
Run Code Online (Sandbox Code Playgroud)
当我从其他地方调用模块时这很好用,但是当我在更改当前工作目录后调用模块时,它会中断.问题是内容__file__是一个相对路径,没有考虑到我更改目录的事实:
>>> mymodule.__file__
'mymodule/__init__.pyc'
>>> os.chdir('..')
>>> mymodule.__file__
'mymodule/__init__.pyc'
Run Code Online (Sandbox Code Playgroud)
如何__file__编写绝对路径,或者禁止如何访问模块中的资源,无论当前工作目录是什么?谢谢!
我编写了一个Python包,其中包含一个bsddb数据库,其中包含一个更耗时的计算的预计算值.为简单起见,我的安装脚本将数据库文件安装在与访问数据库的代码相同的目录中(在Unix上,类似于/usr/lib/python2.5/site-packages/mypackage/).
如何存储数据库文件的最终位置,以便我的代码可以访问它?现在,我正在使用基于__file__访问数据库的模块中的变量的hack :
dbname = os.path.join(os.path.dirname(__file__), "database.dat")
它有效,但看起来......是hackish.有一个更好的方法吗?我想让安装脚本从distutils模块中获取最终安装位置,并将其填入"dbconfig.py"文件,该文件与访问数据库的代码一起安装.
我的包几乎完全是用 python 编写的。但是,某些功能基于在 python 中使用subprocess. 如果我在本地设置包,我需要首先编译相应的 C++ 项目(由 CMake 管理)并确保在 bin 文件夹中创建生成的二进制可执行文件。然后我的 python 脚本就可以调用这些实用程序。
我的项目的文件夹结构类似于以下内容:
root_dir
- bin
- binary_tool1
- binary_tool2
- cpp
- CMakeLists.txt
- tool1.cpp
- tool2.cpp
- pkg_name
- __init__.py
- module1.py
- module2.py
- ...
LICENSE
README
setup.py
Run Code Online (Sandbox Code Playgroud)
我现在考虑创建一个可分发的 python 包并通过PyPi/pip发布它。因此,我需要将 C++ 项目的构建步骤包含到打包过程中。
到目前为止,我创建了 python 包(没有二进制“有效负载”),如本教程中所述。我现在想知道如何扩展打包过程,以便 C++ 二进制文件与包一起分发。
问题:
setuptools专为这样的用例而设计的吗?我相信用 C 代码扩展纯 python 包的规范方法是创建“二进制扩展”(例如使用distutils,或如此处所述)。在这种情况下,功能由可执行文件提供,而不是由可包装的 C/C++ 函数提供。我想避免重新设计 C++ 项目来创建二进制扩展。
我正在尝试将我正在处理的简单网络抓取应用程序的后端放入一个包中,但该应用程序依赖于从腌制的 python 对象加载,我无法使用 importlib 将其加载到文件中. 以前,当我将所有代码都放在一个文件中并依赖于 open() 时,一切正常,但现在我在导入包时出现错误。出现此错误后,我尝试使用 importlib 加载文件,但无法使其工作。
我正在按照来自类似问题的此答案中的步骤进行操作:How to read a (static) file from inside a Python package? .
我的包中的文件结构是:
mypackage\
__init__.py
parse.py
search.py
categories\
categories.pickle
generate_categories_if_corrupted.py
Run Code Online (Sandbox Code Playgroud)
init .py的内容:
from %mymodule% import search
Run Code Online (Sandbox Code Playgroud)
发生错误的代码:
import importlib.resources as resources
from pickle import load
from . import categories
try:
with resources.open_binary(categories, "categories.pickle") as cat:
CATS = load(cat)
except FileNotFoundError:
raise FileNotFoundError("")
Run Code Online (Sandbox Code Playgroud)
错误:
Traceback (most recent call last):
File "%mypackage%\parse.py", line 15, in <module>
with resources.open_binary(categories, "categories.pickle") as cat: …Run Code Online (Sandbox Code Playgroud) 在我尝试分发的包的本地版本中,我有以下代码:
shutil.copytree(WWW_LOCATION, dir_path)
Run Code Online (Sandbox Code Playgroud)
WWW_LOCATION 是我的 python 模块的子文件夹,其中包含一些静态文件和文件夹:
dv
\dv
mytool.py
\www_folder
\somefolders_and_files
setup.py
MANIFEST.in
README.md
LICENSE
setup.cfg
Run Code Online (Sandbox Code Playgroud)
在我的代码中,在执行之后,我需要将整个文件夹与一些动态生成的文件一起复制到用户指定的位置。这在本地效果很好,但我读到了通过 pypi 分发的内容,我必须小心,因为文件可能会被压缩。
这个答案解释了如何访问资源中的内容(=在 python 中读取它们),但是,一次只能访问一个文件。将文件夹内容复制到指定位置的安全方法是什么?