Python_9 py文件导入和路径处理

Posted 甜~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python_9 py文件导入和路径处理相关的知识,希望对你有一定的参考价值。

包:init.py 文件是包的标识符,在导入包的时候会自动执行,有这个文件就是包。 模块:.py结尾的文件叫模块 结构:项目>包>模块,在项目右键New>Python package

一、查缺补漏

  1. Python中两个值交换可以直接交换如:a,b=b,a

  2. 冒泡就是从小到大排序,因为越到后越大

  3. 自动导包也适用于自己创建的模块

  4. 关于正斜杠和反斜杠https://www.cnblogs.com/yangjian319/p/4801675.html

   5. 内置异常汇总https://www.cnblogs.com/nmb-musen/p/10856023.html

   6. HTTP接口传输数据常用的方式https://www.cnblogs.com/xianmin/p/13971389.html

   7. 执行选中的代码快捷键 alt + shift + e

二、模块(py文件)导入

  1. 概念

    1. 包:init.py 文件是包的标识符,在导入包的时候会自动执行,有这个文件就是包。

    2. 模块:.py结尾的文件叫模块

    3. 结构:项目>包>模块,在项目右键New>Python package

  2. 模块导入 import

    1. 模块的分类

      1. python自带模块,本来就有的直接导入就行,如time

      2. 第三方模块,要安装才能导入引用,如requests

      3. 自定义的模块,自己写的py文件,如homework.py

    2. python内py文件的导入:import 模块名称 使用: 模块名称.要使用的内容

    3. 自建py文件的导入:import 模块名称

from 模块名称 import 类名称、函数名称、变量(标识符)指要使用的内容

  1. *:表示导入所有的变量、函数、类

  2. 导包遇到的问题

    1. 导入包时明明看到有这个包但是导不了导包时有语法提示,红波浪线:

      1. 导包的顺序有问题,没有遵守导包格式或计算机找不到包

解决方法:查询应在什么目录下的文件才能找到,将文件移到地址下(查看python变量)

import sys print(sys.path) 结果为一堆地址

  1. 如果不在移动到地址下的操作:

pycharm包管理--包(右键)>Mark Directory as> sources root

  1. 打开的根目录有多个项目,也会出问题:应该从项目开始导入

from 项目名称.模块名称 import 类名称、函数名称、变量(标识符)

三、路径处理

  1. 获取路径

    1. 获取当前py文件的绝对路径,返回结果包括文件名

print(_ file _)

  1. 获取当前文件所在目录的绝对路径,不包括文件名 导入os import os

result = os.path.dirname(_ file _) print(result)

  1. 查看当前工作路径--工作路径可以使用os.chdir()进行切换会但集成到git中

    1. 在同一路径下直接输入dir命令可查看

    2. 在不同的路径时使用代码:res = os.getcwd() print(res)

  2. 返回指定文件的绝对路径,不是查询功能是拼接功能,将指定的文件拼接到当前的相对路径下

res = os.path.abspath("指定的文件") print(res)

  1. 路径拼接 os.path.join(path1,path2.....) path装着地址

    1. 不显示添加\\,会自动补齐

如:path1="member"

path2="login"

path3="index.html"

res = os.path.join(path1,path2,path3) 结果为:member\\login\\index.html

  1. 添加\\时会以斜杠的为开始,斜杠之前的都舍弃,多个路径有\\会以最后一个带\\的路径为开始路径前面的会丢弃掉,这个路径为绝对路径,如果每个路径都加了\\,会以最后一个为准,前面的都会被舍弃掉

如: import os

path1="member"

path2="\\login"

path3="index.html"

res = os.path.join(path1,path2,path3)

print(res) 结果为\\login\\index.html

  1. 其他方法

    1. os.mkdir(path,mode) 创建目录 path里装路径,mode是权限

    2. os.chdir(path) 切换工作目录,最好不切目录

    3. os.rmdir(path) 删除空目录,删除空文件夹,一定要是空的

    4. os.listdir(path) 返回指定路径下的文件或者目录如[\'.idea\', \'homework.py\'],像Terminal中的dir命令

    5. os.path.isdir(path) 判断是否是目录,返回True和False

    6. os.path.isfile(path) 判断是否是文件,返回True和False

    7. os.remove(file) 删除文件 file="要删除的文件名" 同目录下,路径是一个目录,将抛出OSError

    8. os.removedirs(file) 只能删除子文件夹中的空文件夹,非空无法删除

    9. shutil.rmtree(file) 表示递归删除文件夹下的所有子文件夹和子文件

 

  1. 魔术方法 以双下划线开头以双下划线结尾的方法叫魔术方法~

    1. _ file _:当前文件的绝对路径

    2. _ name _:获取函数的名称

列:print(要查询的函数._ name _) 结果为:函数名

  1. _ doc _:获取函数的注释内容(多行注释)

列:print(要查询的函数._ _doc _ _) 结果为:函数开发时的注释

  1. _ dict _:获取对象的所有属性【掌握】

列:print(要查询的函数._ _doc _ _) 结果为:函数的一堆属性

四、异常处理

  1. 异常:当程序在运行过程中遇到了一个错误,无法执行,出现的一些提示和报错信息

  2. 常见异常:

    1. NameError : name \'xx\' is not defined 名字xx没找到,使用一个还未赋予对象的变量

    2. SyntaxError : unexpected EOF while parsing 语法错误

    3. IndexError: list index out of range 范围越界了超出边界,没有值

    4. KeyError: \'10\' 没有这个值,找不到,空指针

    5. IOError:输入输出异常

    6. AttributeError:试图访问一个对象没有的属性

    7. ImportError:无法引入模块或包,基本是路径问题

    8. IndentationError:语法错误,代码没有正确的对齐

 

  1. 异常捕获:为了代码在错了之后继续执行

    1. try:...except: 在try后输入可能存在异常的代码,except之后输入用户可以看到的回复

try:

print("可能出现异常的代码")

except:

print("代码执行报错之后执行的代码")

  1. finally 类似于if…else,如果try后的有报错,则走except,走完之后再走finally

try:

print("可能执行报错的代码")

except:

print("代码执行报错之后执行的代码")

finally:

print("不管代码执行是否报错都会执行的代码")

  1. else 如果try后的有报错,则走except,如果try后没有报错则走else

try:

#print(name)

print("可能执行报错的代码")

except:

print("代码执行报错之后执行的代码")

else:

print("代码执行不报错的时候执行这里的代码")

  1. traceback Exception 异常抛出

解释:try后的代码有报错则except中的e输出报错内容,traceback.print_exc()输出错误在哪,然后再执行except的代码,当try不报错的时候执行else后的代码,这个方法需要导入库import traceback

try:

print(name)

print("可能执行报错的代码")

except Exception as e :

print(e)

print(traceback.print_exc()) -------------自动化时标红的内容需要收入日志

print("代码执行报错之后执行的代码")

else:

print("代码执行不报错的时候执行这里的代码")

  1. raise 自定义异常 断言

解释:当捕获print(name)报错之后要把raise Exception("这里是异常")抛出

try:

print(name)

print("可能执行报错的代码")

except Exception as e :

raise Exception("这里是异常")

 

五、一些知识点

  1. pycharm中配置setting>Editor>General>Auto Import 和导包有关的配置

  2. 快速自动导包:想要导入x,可以通过自动导报快捷键,直接出现import 模块名,不用手动码字

    1. windows: 鼠标放置x,alt+回车

    2. mac:鼠标放置x,option+回车

  3. 绝对路径:总是从根文件夹开始,Window 系统中以盘符(C:、D:)作为根文件夹,而 OS X 或者 Linux 系统中以 / 作为根文件夹。

  4. 相对路径:指的是文件相对于当前工作目录所在的位置。例如,当前工作目录为 "C:\\Windows\\System32",若文件 demo.txt 就位于这个 System32 文件夹下,则 demo.txt 的相对路径表示为 ".\\demo.txt"

 

 

 

从 Python 中的相对路径导入

【中文标题】从 Python 中的相对路径导入【英文标题】:Importing from a relative path in Python 【发布时间】:2011-11-22 06:55:47 【问题描述】:

我有一个存放客户端代码的文件夹、一个存放服务器代码的文件夹,以及一个存放它们之间共享的代码的文件夹

Proj/
    Client/
        Client.py
    Server/
        Server.py
    Common/
        __init__.py
        Common.py

如何从 Server.py 和 Client.py 导入 Common.py?

【问题讨论】:

相关:***.com/q/72852/1025391 【参考方案1】:

我使用的方法与上面提到的 Gary Beardsley 类似,只是略有改动。

文件名:Server.py

import os, sys
script_path = os.path.realpath(os.path.dirname(__name__))
os.chdir(script_path)
sys.path.append("..")
# above mentioned steps will make 1 level up module available for import
# here Client, Server and Common all 3 can be imported.

# below mentioned import will be relative to root project
from Common import Common
from Client import Client

【讨论】:

【参考方案2】:

不要进行相对导入。

来自PEP8:

强烈建议不要使用包内导入的相对导入。

将所有代码放入一个超级包(即“myapp”),并为客户端、服务器和通用代码使用子包。

更新:Python 2.6 和 3.x 支持正确的相对导入 (...)”。详情请见Dave's answers。

【讨论】:

想象一下,您在“if __name__ == "__main__":”行之后将一些代码添加到客户端和服务器的末尾。也就是说,您希望能够将它们用作独立脚本。如何正确地做到这一点?我认为这是一个非常常见的用例,应该得到支持。为什么不鼓励? 我很惊讶“不要这样做”是“我如何...”问题的公认答案(好吧,Rails 除外。)有 偶尔这样做的原因。我使用类似于 Dave 建议的解决方案。 @TomWilson:这不是纯粹的“不要这样做”的答案。下面有“这样做”。 有人应该告诉 Numpy 的人!他们使用了大量的相对进口! 此答案不适用于当前版本的 Python。在 PEP 8 中不再找到引用的部分。现在它的内容如下:“显式相对导入是绝对导入的可接受替代方案,尤其是在处理复杂的包布局时,使用绝对导入会不必要地冗长”【参考方案3】:

很有趣,我刚刚遇到了同样的问题,我通过以下方式完成了这项工作:

结合linux命令ln,我们可以让事情变得简单很多:

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

而且,现在如果你想将some_stuff 从文件:Proj/Common/Common.py 导入到你的文件:Proj/Client/Client.py,就像这样:

# in Proj/Client/Client.py
from Common.Common import some_stuff

而且,这同样适用于Proj/Server,也适用于setup.py 进程, a same question discussed here,希望对你有帮助!

【讨论】:

【参考方案4】:

2014 年 11 月编辑(3 年后):

Python 2.6 和 3.x 支持适当的相对导入,您可以避免做任何不合时宜的事情。使用这种方法,您知道您获得的是 relative 导入,而不是 absolute 导入。 '..' 的意思是,转到我上面的目录:

from ..Common import Common

需要注意的是,这仅在您从包的外部将python作为模块运行时才有效。例如:

python -m Proj

原始的hacky方式

这种方法在某些情况下仍然很常用,在这些情况下,您实际上并没有“安装”您的包。例如,它在 Django 用户中很受欢迎。

您可以将 Common/ 添加到您的 sys.path(python 用来导入内容的路径列表):

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common'))
import Common

os.path.dirname(__file__) 只是给你当前 python 文件所在的目录,然后我们导航到 'Common/' 目录并导入 'Common' 模块。

【讨论】:

不要手动修改python模块路径,可能只是为了快速破解。使用 distutils、setuptools 等学习 Python 包管理通常是解决此类问题的必备技能。 @SaschaGottfried 完全同意,尽管如果您不制作可分发的包,这可能无关紧要。例如,在 Django 中,您永远不会真正使用 distutils 安装您的应用程序,因此上述方法很容易破解。但无论如何,我已经用我这些天要做的事情编辑了答案。 感谢您回答实际问题,而不是宣传正确的技术。进行相对导入有很多充分的理由。 要再上一层,每层使用一个额外的点。 @jxramos ex:from ...myfile 转到 ../../myfile @WattsInABox 你将如何上到另一个目录中的文件,比如../../mydir2/myfile【参考方案5】:

进行相对导入是绝对可以的!以下是 little 'ol me 所做的:

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py

【讨论】:

但是您最好知道 sys.argv[0] 实际指向的位置 - 它(prolly)不是您启动 python 时所在的目录。 这是一个快速破解,有很多陷阱。但问题也好不到哪里去。 写得很清楚,但是Dave's answer 中的原始hack 更好,因为它使用__file__ 从当前文件中获取正确的关系【参考方案6】:

默认导入方法已经是“相对”的,来自 PYTHONPATH。默认情况下,PYTHONPATH 与原始源文件的文件夹一起指向某些系统库。如果使用 -m 运行模块,则当前目录将添加到 PYTHONPATH。因此,如果您的程序的入口点在 Proj 内部,那么使用 import Common.Common 应该可以在 Server.py 和 Client.py 中使用。

不要进行相对导入。它不会按照你想要的方式工作。

【讨论】:

如果这是真的,为什么最重要的答案没有这样说?这行得通吗?

以上是关于Python_9 py文件导入和路径处理的主要内容,如果未能解决你的问题,请参考以下文章

python - 路径处理 和 模块导入

python第五天

Pytest权威教程24-Pytest导入机制及系统路径

python怎么导入自己写的包

如何在python3中正确导入同一目录下的模块

模块之相对路径导入