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

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

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

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

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

推荐 Vocabulary.com

阅读之前如果你还在思考背单词的意义,我建议你先想清楚,或者参考别人的意见,例如知乎的讨论 背单词是必须吗 等问题。 从英语方面来说,我肯定不是大神,小神都算不上。 我背单词的路径基本是 中学大学英语书附录 -> 高频词汇书 -> 扇贝单词 -> Vocabulary.com。 那为什么要来推荐 Vo

Comments