Python中各种import使用

先看两个清爽的,轻量级的入门。
https://www.cnblogs.com/AlwinXu/p/5658787.html
https://blog.csdn.net/qq_39607437/article/details/79298304
一般来说知道上面两个的内容,日常需求基本已经够用了。。
如果想进一步了解更多,再来看我后面的更细致的分析。

一般来说使用全部路径来导入(绝对导入),是最安全的。

该网友:

https://www.cnblogs.com/zynzyf/p/9951984.html
python3 SystemError: Parent module ‘’ not loaded, cannot perform relative import

1.今天在学校Django的时候源文件里有两处导入一直出错,没有修改过的运行就是报错,提示SystemError: Parent module ‘’ not loaded, cannot perform relative import,项目目录如下:

在这里插入图片描述在这里插入图片描述
往__init__中导入config和registry始终不行,就提示 SystemError: Parent module ‘’ not loaded, cannot perform relative import,网上百度了很久,最后用下面的方法解决了

  1. from django.apps.config import AppConfig
    from django.apps.registry import apps

使用全部路径导入就可以了,没有报错了






又如网友:

https://blog.csdn.net/sunhuaqiang1/article/details/72801317
https://blog.csdn.net/muttry/article/details/82812134

SystemError: Parent module ‘’ not loaded, cannot perform relative import

解决:循环导包,导包路径出错

定位到views.py中,删除了导包语句

from . import Users
重新导入,把 . 换成具体路径
from app.db import Users

跟改所有类似的导包,右击,点击=== 应用级文件夹-——> Mark as——>SourceRoot
这个过程我觉得就是把当前文件夹加入系统搜素路径而已。。

也有网友找到了经验规律。。
https://blog.csdn.net/huhehaotechangsha/article/details/80699114

不知道这个原因是什么,但是找到了有效的解决方法

1、请将你的需要导入其他文件函数的主文件放在工程的最外层。
2、然后,将其他需要导入的文件分类放入各个文件夹中。
3、切记,和主文件平行关系的是各个文件夹,而不是各个.py 文件。这样导入就不会出错

下面两个图分别是正确的和不正确的文件放置,以及导入方式。
在这里插入图片描述
在这里插入图片描述






再如:

https://blog.csdn.net/weixin_42034322/article/details/81215072
这个人文字写的有点问题,我已经修正如下。

Python引入同级包和模块的方法

工程项目结构如下:
在这里插入图片描述
包AnimalShow和Class_test是同级包,Animal是父类,Gound,Sea,Sky继承它,Chicken继承Gound_Animals与Sky_Animals。

首先是Gound.py引入Animal模块,如下

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from AnimalShow.Animal import Animals
 
class Gound_Animal(Animals) :
    def __init__(self , name , age , message):
        self.age = age
        self.name = name
        self.message = message
        print("Gound_Animal初始化完毕")
 
    def printA(self):
        print("name : %s, age : %d, message : %s" % (self.name, self.age, self.message))
 
    def GG(self):
        print("我是Gound_Animal独有方法")

Sky和Sea同理,
下面是同级包的导入,Chicken引入Gound和Sky,如下,

#!/usr/bin/python
# -*- coding: UTF-8 -*-
from AnimalShow import Gound_Animals,Sky_Animals
 
class chicken(Gound_Animals.Gound_Animal,Sky_Animals.Sky_Animal):
 
    def __init__(self, name, age, message):
            self.age = age
            self.name = name
            self.message = message
            print("chicken初始化完毕")
    def printA(self):
        print("name : %s, age : %d, message : %s" % (self.name, self.age, self.message))
    def CC(self):
        print("我是chicken独有方法")
 
if __name__ == "__main__":
    GA = Gound_Animals.Gound_Animal("陆地动物",10,"我是陆地动物")
    CK = chicken("小鸡",2,"小鸡")
    CK.printA()
    CK.CC()
    CK.GG()
    CK.hobby()

测试结果:
在这里插入图片描述






以上是比较通用的情况,在任何目录任何工作空间都可以运行。
但是,
如果涉及到工作空间,工作区os.cwd(),更准确的说是,比如你在特定编辑器vscode打开一个工作区,你再打开一个py文件,但是你运行的这个py脚本不在这个工作区里,那么默认的,此时的工作区是属于你打开的这个工作区,而无法使用你这个脚本所在的工作区(也就是文件夹啦。。)。又或者你使用命令行terminal,powershell,或者什么自带的命令行运行这个脚本,效果也是一样的,但命令行通常是在哪里运行,哪里就是工作目录。所以说,编辑器所属的工作空间是强制的,但是它却并没有把本路径加入搜索路径,这是最蛋疼的,而且编辑器里面就算是你运行这个脚本,它也是在这个工作区,然后重定向,按照绝对路径运行你这个脚本的,但工作空间永远是他的,你仍然可以使用它自带的import文件关系,但就是不给你想要的工作空间值os.getcwd(),除非是你通过什么方式强行改变,更换工作空间。总结一句,其实也很简单,其实设么也不影响,就是影响os.getcwd()的值。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
编辑器pycharm的坑:
https://blog.csdn.net/qq_37791134/article/details/83592762

在pycharm中import同级目录中py文件(在一个package中)时会出现错误。
pycharm不会将当前文件目录自动加入自己的sourse_path。右键make_directory as–>Sources Root将当前工作的文件夹加入source_path就可以了
在这里插入图片描述
在这里插入图片描述
其实我觉得一般都不会自动加入吧,vscode也不会,这种方法要么是你自己设计不合理,要么是你需要手动加入搜索路径(迫不得已的话。。)。

而你运行的其他脚本不在这个工作区的话,可能就会产生import等问题。
比如:https://blog.csdn.net/xm_csdn/article/details/52211079
python实现不同层级目录import 模块的方法

python目前也像php一样越来越多的朋友使用它了,今天 小编在学习python时碰到不同层级引用的问题,希望可以帮助到大家。

一、同级目录下的调用

程序结构如下:

-- src
    |-- mod1.py
    |-- test1.py

若在程序test1.py中导入模块mod1, 则直接使用

import mod1

from mod1 import *;

二、调用子目录下的模块

程序结构如下:

-- src
    |-- mod1.py
    |-- lib
    |    |-- mod2.py
    |-- test1.py

这时看到test1.py和lib目录(即mod2.py的父级目录),如果想在程序test1.py中导入模块mod2.py ,可以在lib件夹中建立空文件__init__.py文件(也可以在该文件中自定义输出模块接口),然后使用:

from lib import mod2

import lib.mod2

三、调用上级目录下的文件

程序结构如下:

-- src
    |-- mod1.py
    |-- lib
    |    |-- mod2.py
    |-- sub
    |    |-- test2.py

这里想要实现test2.py调用mod1.py和mod2.py ,做法是我们先跳到src目录下面,直接可以调用mod1,然后在lib上当下建一个空文件__init__.py ,就可以像第二步调用子目录下的模块一样,通过from lib import mod2进行调用了。具体代码如下:

import sys

import os

# 得到当前根目录

o_path = os.getcwd()

sys.path.append(o_path)
import mod1
from lib import mod2

但是吧,我觉得一般很少这样做吧。。
在这里插入图片描述
你还别说,这逼还真可以运行,但前提是你设置对了工作空间,否则你就会出现找不到sub这个module这样的错误。
其实更高级的,一般会使用__file__这个关键字进行路径获取,避免上面os.getcwd()带来的bug。。
比如:
https://blog.csdn.net/weixin_38105245/article/details/78611756
https://blog.csdn.net/weixin_42100915/article/details/80247530
python 在import同级目录下文件会出现找不到module问题

正确解决方法为在导入之前手动添加目录,添加如下代码

current_dir = os.path.abspath(os.path.dirname(__file__))
sys.path.append(current_dir)
sys.path.append("..")

linux 目录文件中含有__init__.py 文件既为 包 可以在当目录下创建模块

__init__.py 文件为空

__init__.py 中,可定义  __all__= ["echo","surround","reverse"] 

看看这个
http://www.cnblogs.com/vamei/archive/2012/07/03/2574436.html
可以有个最基本的认识。

这意味着, from sound.effects import * 会从对应的包中导入以上三个子模块; 尽管提供 import * 的方法,仍不建议在生产代码中使用这种写法。
pycharm 中可以直接创建包
导入模块:会直接执行一遍模块

# **** 使用 点(.) 连接packet(包) 引用模块
from q.q1.q2 import qq   # pycharm 会有红色下划线 可以使用不用理会
qq.z()
from q.q1.q2.qq import z
z()

当然,模块中含有:if __name__ == '__main__':下面的代码不会执行

import sys
print(sys.path)   # 查看默认导入模块路径
sys.path.append()  # 临时添加环境变量

添加环境变量 可以导入当前位置

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # 不限文件位置 添加环境变量

sys.path.append(BASE_DIR)

print(BASE_DIR)

这里,补充几个python内置模块,os,sys的知识。

1、os.path.dirname(path)

语法:os.path.dirname(path)
功能:去掉文件名,返回目录
如:

print(os.path.dirname("E:/Read_File/read_yaml.py"))
#结果:
E:/Read_File
print(os.path.dirname("E:/Read_File"))
#结果:
E:/

2、os.path.dirname(__file__)

先了解一下__file_,这个东西需要具体的脚本文件

print(__file__)
#结果
E:/Read_File/read_yaml.py

可以看出__file__表示了当前文件的path

那么就可以了解到os.path.dirname((file)和os.path.dirname(“E:/Read_File/read_yaml.py”)是一个意思
再根据os.path.dirname(path)的用法,得出os.path.dirname((file)就是得到当前文件的绝对路径

print(os.path.dirname(__file__))
#结果:
E:/Read_File

扩展

若print os.path.dirname(file)所在脚本是以绝对路径运行的,则会输出该脚本所在的绝对路径,若以相对路径运行,输出相对目录

print(os.path.dirname(__file__))

在命令行terminal以相对路径运行脚本的话python -.py,输出相对目录
在这里插入图片描述

Python 获取当前所在目录的方法详解

参考: https://blog.csdn.net/nalnait/article/details/80872427

1、 sys.path

模块搜索路径的字符串列表。由环境变量PYTHONPATH初始化得到。

sys.path[0]是调用Python解释器的当前脚本所在的目录。

2、 sys.argv

一个传给Python脚本的指令参数列表。

sys.argv[0]是脚本的名字(由系统决定是否是全名)

假设显示调用python指令,如 python demo.py ,会得到绝对路径;

若直接执行脚本,如 ./demo.py ,会得到相对路径。

os.getcwd()

获取当前工作路径。在这里是绝对路径。
https://docs.python.org/2/library/os.html#os.getcwd

3、 __file__

获得模块所在的路径,可能得到相对路径。

如果显示执行Python,会得到绝对路径。

若按相对路径来直接执行脚本 ./pyws/path_demo.py ,会得到相对路径。

为了获取绝对路径,可调用 os.path.abspath()

os.path 中的一些方法

4、 os.path.split(path)

将路径名称分成头和尾一对。尾部永远不会带有斜杠。如果输入的路径以斜杠结尾,那么得到的空的尾部。

如果输入路径没有斜杠,那么头部位为空。如果输入路径为空,那么得到的头和尾都是空。
https://docs.python.org/2/library/os.path.html#os.path.split

5、 os.path.realpath(path)

返回特定文件名的绝对路径。

https://docs.python.org/2/library/os.path.html#os.path.realpath

代码示例

环境 Win7, Python2.7

以 /e/pyws/path_demo.py 为例
代码如下:

#!/usr/bin/env python
import os
import sys
 
if __name__ == '__main__':
  print "sys.path[0] =", sys.path[0]
  print "sys.argv[0] =", sys.argv[0]
  print "__file__ =", __file__
  print "os.path.abspath(__file__) =", os.path.abspath(__file__)
  print "os.path.realpath(__file__) = ", os.path.realpath(__file__)
  print "os.path.dirname(os.path.realpath(__file__)) =", os.path.dirname(os.path.realpath(__file__))
  print "os.path.split(os.path.realpath(__file__)) =", os.path.split(os.path.realpath(__file__))
  print "os.getcwd() =", os.getcwd()

在 /d 中运行python /e/pyws/path_demo.py,输出为

$ python /e/pyws/path_demo.py
sys.path[0] = E:\pyws
sys.argv[0] = E:/pyws/path_demo.py
__file__ = E:/pyws/path_demo.py
os.path.abspath(__file__) = E:\pyws\path_demo.py
os.path.realpath(__file__) = E:\pyws\path_demo.py
os.path.dirname(os.path.realpath(__file__)) = E:\pyws
os.path.split(os.path.realpath(__file__)) = ('E:\\pyws', 'path_demo.py')
os.getcwd() = D:\

在e盘中用命令行直接执行脚本./pyws/path_demo.py

$ ./pyws/path_demo.py
sys.path[0] = E:\pyws
sys.argv[0] = ./pyws/path_demo.py
__file__ = ./pyws/path_demo.py
os.path.abspath(__file__) = E:\pyws\path_demo.py
os.path.realpath(__file__) = E:\pyws\path_demo.py
os.path.dirname(os.path.realpath(__file__)) = E:\pyws
os.path.split(os.path.realpath(__file__)) = ('E:\\pyws', 'path_demo.py')
os.getcwd() = E:\

python获取当前路径

import os,sys
使用sys.path[0]、sys.argv[0]、os.getcwd()、os.path.abspath(file)、os.path.realpath(file)
sys.path是Python会去寻找模块的搜索路径列表,sys.path[0]和sys.argv[0]是一回事因为Python会自动把sys.argv[0]加入sys.path。
如果你在C:\test目录下执行python getpath\getpath.py,那么os.getcwd()会输出“C:\test”,sys.path[0]会输出“C:\test\getpath”。
如果你用py2exe模块把Python脚本编译为可执行文件,那么sys.path[0]的输出还会变化:
如果把依赖库用默认的方式打包为zip文件,那么sys.path[0]会输出“C:\test\getpath\libarary.zip”;
如果在setup.py里面指定zipfile=None参数,依赖库就会被打包到exe文件里面,那么sys.path[0]会输出“C:\test\getpath\getpath.exe”。

#!/bin/env python
#-*- encoding=utf8 -*-

import os,sys

if __name__=="__main__":

    print "__file__=%s" % __file__

    print "os.path.realpath(__file__)=%s" % os.path.realpath(__file__)

    print "os.path.dirname(os.path.realpath(__file__))=%s" % os.path.dirname(os.path.realpath(__file__))
  
    print "os.path.split(os.path.realpath(__file__))=%s" % os.path.split(os.path.realpath(__file__))[0]  

    print "os.path.abspath(__file__)=%s" % os.path.abspath(__file__)

    print "os.getcwd()=%s" % os.getcwd()

    print "sys.path[0]=%s" % sys.path[0]

    print "sys.argv[0]=%s" % sys.argv[0]

输出结果:
D:\>python ./python_test/test_path.py
__file__=./python_test/test_path.py
os.path.realpath(__file__)=D:\python_test\test_path.py
os.path.dirname(os.path.realpath(__file__))=D:\python_test
os.path.split(os.path.realpath(__file__))=D:\python_test
os.path.abspath(__file__)=D:\python_test\test_path.py
os.getcwd()=D:\
sys.path[0]=D:\python_test
sys.argv[0]=./python_test/test_path.py

os.getcwd() “D:\”,取的是起始执行目录
sys.path[0]或sys.argv[0] “D:\python_test”,取的是被初始执行的脚本的所在目录
os.path.split(os.path.realpath(file))[0] “D:\python_test”,取的是__file__所在文件test_path.py的所在目录

正确获取当前的路径:

__file__是当前执行的文件



# 获取当前文件__file__的路径

print "os.path.realpath(__file__)=%s" % os.path.realpath(__file__)

# 获取当前文件__file__的所在目录

print "os.path.dirname(os.path.realpath(__file__))=%s" % os.path.dirname(os.path.realpath(__file__))   
# 获取当前文件__file__的所在目录

print "os.path.split(os.path.realpath(__file__))=%s" % os.path.split(os.path.realpath(__file__))[0] 

总结一下:

    py文件所在位置/test/pj/hello.py
    用户所在位置:/
    
    用户执行命令python /test/pj/hello.py
    
    1. os.getcwd()
    
      返回的是执行命令的位置 /
    
    2.sys.paht[0]
    
      返回的是脚本所在的位置 /test/pj/

【Python】Python获取,以及设置当前工作目录
在使用Python时,有时需要对当前操作系统做相应的操作,比如获取当前工作目录。下面简单介绍了获取当前工作目录和改变当前工作目录的方法,供参考。

获取当前工作目录

os.getcwd() #用以获取当前的工作目录

改变当前工作目录

os.chdir(path) #用于改变当前工作目录到指定的路径

参数:

Path --要切换到的路径。
返回值:如果允许访问返回True,否则返回False。

例子:

#-*-coding:utf-8-*-
import os,sys

path = 'D:\\'

#查看当前工作目录
print("当前的工作目录为:%s" %os.getcwd())

#修改当前工作目录
os.chdir(path)

#查看修改后的工作目录
print("目录修改成功 %s" %os.getcwd())





再看一个问题:

深度理解Python import 功能
https://blog.csdn.net/geekleee/article/details/52505233

本来以为已经理解了import功能,没想到实际应用了还有这么多门道
比如,不通过模块名字,直接引入模块内的类
我们创建一个包叫ccc,然后下面的init里面什么也没写,都是空的
然后bbb.by里面的内容是:

def a():
    print (1)

如果你要访问这个函数a
首先第一点,一个写法:
from ccc.bbb import a ,注意,他只能通过 包名.模块名来import具体函数
如果你直接用from ccc import a ,是会报警的,报警如下:

>>> from ccc import a
Traceback (most recent call last):
  File "<input>", line 1, in <module>
ImportError: cannot import name 'a'

其实,关键是,如果你要通过from ccc import a,重要的是init的内容
如果我们把init内容写成下图3
from .bbb import a,这里面的 .bbb是什么意思呢?就是在同级目录下面的bbb模块,如果前面是2个点,那就是上级目录的bbb

现在,要讲一个重要概念!!!
当你导入一个包的时候,实际上是导入了这个包的init.py的文件,所以,如果你在init里面写入了其他的import功能,就等于是在初始化的时候帮忙导入了其他东西。
就比如下面的例子,他在导包的时候,就顺便导入了a这个函数!!

在这里插入图片描述
从这个话题引申到其他话题,我在做flask第一节课的时候一直无法理解,为什么from flask import Flask可以成功?
第一个flask是包,第二个Flask是类,但是,实际上这个Flask类是在flask包的目录下app.py里面的。
所以后来我去看了flask包的init.py,原来在里面,他已经帮你导入了Flask类,所以你在导入flask包的时候,就已经可以直接导Flask类了
看到里面的 from .app import Flask, Request, Response
.app就表示了在flask包下,和init同级的app.py

在这里插入图片描述

在包内运行文件,如果需要导入包的内容,一定要注意不可使用相对路径

SystemError: Parent module ‘’ not loaded, cannot perform relative import

其实关于这点,不用不知道,很多国外的哥们也在吐槽,python的import机制怎么这么繁琐。。详见下面的链接:
https://blog.51cto.com/11163489/1976988
https://stackoverflow.com/questions/16981921/relative-imports-in-python-3#
https://www.cnblogs.com/cposture/p/5492351.html?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io#_label0
https://stackoverflow.com/questions/33837717/systemerror-parent-module-not-loaded-cannot-perform-relative-import
https://stackoverflow.com/questions/11536764/how-to-fix-attempted-relative-import-in-non-package-even-with-init-py

但其实,python就是这样,他并没有强行规定一些准则,自身具有很大的灵活性,导致了一些没有预料到的bug,

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值