Python文件(脚本)的绝对路径

Posted on 2015-05-11 by Shawn Wang

Posted in python

今天遇到一个在Python下绝对路径的问题, 因为错误这个错误小小的折腾了一翻, 故对怎样在Python项目中获取对应想要的路径问题进行部分的总结, 特别是避免os.getcwd()函数容易引起的误区。

先描述一下遇到的问题,在路径如下的项目中:

project
|-- config
    |-- __init__.py
    |-- data.db
|-- src
    |-- dao.py

config/__init__.py 中定义了一个常量:

# 数据库文件路径
db_path = "data.db"

dao.py 文件内容如下:

import sqlite3
from config import db_path

class Dao:

    def __init__(self):
        self.conn = sqlite3.connect(db_path)

    def get_menu_count(self):
        print(db_path)
        sql = "SELECT * FROM menu ORDER BY random() limit 1"
        cursor = self.conn.execute(sql)
        for row in cursor:
            print(row[0])
            print(row[1])
            print(row[2])

if __name__ == "__main__":
    Dao().get_menu_count()

执行 dao.py 文件, sqlte3.OperationError: no such table: menu 错误被抛出, 检测SQL语句后我意识到可能是 db_path 路径的问题, 奇怪的是 sqlite3.connect(db_path) 并没有报错。

于是我将 config/__init__.py 修改如下:

# 数据库文件名
db_file = "w2eat_data.db"
# 数据库文件路径
db_path = os.path.join(os.path.getcwd(), db_file)

再次执行 dao.py , 报错依然如下:

C:\Users\shawn\Dropbox\code\python\project\src\data.db
Traceback (most recent call last):
  File "C:\Users\shawn\Dropbox\code\python\project\src\dao.py",
      line 32, in <module> Dao().get_menu_count()
  File "C:\Users\shawn\Dropbox\code\python\project\src\dao.py",
      line 22, in get_menu_count cursor = self.conn.execute(sql)
sqlite3.OperationalError: no such table: menu

注意到, db_path 此刻变成 C:\Users\shawn\Dropbox\code\python\project\src\data.db , 这是因为 os.getcwd() 获取的是当前的工作目录, 所以os.getcwd()获取的并不是脚本文件的目录, 而是所执行的python脚本的目录。

于是再次将 config/__init.py 修改如下:

# 数据库文件名
db_file = "w2eat_data.db"
# 数据库文件路径
db_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), db_file)

再次执行 dao.py , 运行成功:

C:\Users\shawn\Dropbox\code\python\project\config\data.db
1
item
3



总结:

1. os.getcwd()函数

返回当前执行脚本的绝对路径, 即python最初执行的哪个脚本

2. os.path.dirname()函数

返回输入的完整路径加文件的目录路径部分, 如 ~/tmp.md 被输入, 将返回~/

3. os.path.abspath()函数

返回指定文件的绝对路径

4. os.path.abspath()与os.path.realpath()的区别

两者都返回指定文件的绝对路径, 而如果这个文件是你为其他文件创建的一个软链接(symlink), os.path.realpath()还可以获取其真实的路径,而os.path.abspath()不可



python 绝对路径 sqlite3

Donation

Latest Posts

防疫贴士

关于消毒液 1. 很不建议使用酒精,效果一般,建议电子设备消毒时可以小范围使用消毒棉片。 75% 酒精是易燃的,公共场合更容易引发事故。 酒精不是度数越高越好,75% 左右最佳。 挥发快,效果短。 2. 建议用次氯酸钠(84等),很便宜、效果好,家里用很合适。 不要和酸混用,比如洁则灵(威猛先生、蓝

在 VPS 上搭建 Cisco IPsec|L2TP over IPsec 的极简攻略

三年前我写过一篇在VPS上搭建PPTP VPN的极简攻略, 不过一年前我就不再使用 PPTP VPN 了,最主要的原因是因为 macOS 完全不支持 PPTP;另一个原因是基于 ipsec 协议的 VPN 更加安全,IPsec 协议会加密你的网络数据, 避免泄漏或者中间人攻击。所以现在对于需要全局代

为什么应该使用本地广播(LocalBroadcastManager)

Android 诞生已来,就一直有所谓的四大组件,BroadcastReceiver 是其中之一。 几乎在各种样的应用中都有 BroadcastReceiver 的使用,它被应用于接收系统发送的消息以及与其他应用之间的交互,但也被大量的误用于应用内部通信。 然而在同应用中使用则违背 Broadcas

Comments