1.今天在学校Django的时候源文件里有两处导入一直出错,没有修改过的运行就是报错,提示SystemError: Parent module ‘’ not loaded, cannot perform relative import,项目目录如下:
往__init__中导入config和registry始终不行,就提示 SystemError: Parent module ‘’ not loaded, cannot perform relative import,网上百度了很久,最后用下面的方法解决了
- from django.apps.config import AppConfig
from django.apps.registry import apps
使用全部路径导入就可以了,没有报错了
SystemError: Parent module ‘’ not loaded, cannot perform relative import
解决:循环导包,导包路径出错
定位到views.py中,删除了导包语句
from . import Users
重新导入,把 . 换成具体路径
from app.db import Users
跟改所有类似的导包,右击,点击=== 应用级文件夹-——> Mark as——>SourceRoot
这个过程我觉得就是把当前文件夹加入系统搜素路径而已。。
也有网友找到了经验规律。。
不知道这个原因是什么,但是找到了有效的解决方法
1、请将你的需要导入其他文件函数的主文件放在工程的最外层。
2、然后,将其他需要导入的文件分类放入各个文件夹中。
下面两个图分别是正确的和不正确的文件放置,以及导入方式。
再如:
这个人文字写的有点问题,我已经修正如下。
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的坑:
在pycharm中import同级目录中py文件(在一个package中)时会出现错误。
pycharm不会将当前文件目录自动加入自己的sourse_path。右键make_directory as–>Sources Root将当前工作的文件夹加入source_path就可以了
其实我觉得一般都不会自动加入吧,vscode也不会,这种方法要么是你自己设计不合理,要么是你需要手动加入搜索路径(迫不得已的话。。)。
python目前也像php一样越来越多的朋友使用它了,今天 小编在学习python时碰到不同层级引用的问题,希望可以帮助到大家。
一、同级目录下的调用
程序结构如下:
-- src
|-- mod1.py
|-- test1.py
若在程序test1.py中导入模块mod1, 则直接使用
import mod1
或from mod1 import *
;
二、调用子目录下的模块
程序结构如下:
-- src
|-- mod1.py
|-- lib
| |-- mod2.py
|-- test1.py
可以在lib件夹中建立空文件__init__.py文件(也可以在该文件中自定义输出模块接口),然后使用:
from lib import mod2
或
import lib.mod2
三、调用上级目录下的文件
程序结构如下:
-- src
|-- mod1.py
|-- lib
| |-- mod2.py
|-- sub
| |-- test2.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。。
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"]
看看这个
,
可以有个最基本的认识。
这意味着, from sound.effects import *
会从对应的包中导入以上三个子模块; 尽管提供 import *
的方法,仍不建议在生产代码中使用这种写法。
pycharm 中可以直接创建包
导入模块:会直接执行一遍模块
当然,模块中含有: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 获取当前所在目录的方法详解
参考:
1、 sys.path
模块搜索路径的字符串列表。由环境变量PYTHONPATH初始化得到。
sys.path[0]是调用Python解释器的当前脚本所在的目录。
2、 sys.argv
一个传给Python脚本的指令参数列表。
sys.argv[0]是脚本的名字(由系统决定是否是全名)
假设显示调用python指令,如 python demo.py ,会得到绝对路径;
若直接执行脚本,如 ./demo.py ,会得到相对路径。
3、 __file__
获得模块所在的路径,可能得到相对路径。
如果显示执行Python,会得到绝对路径。
若按相对路径来直接执行脚本 ./pyws/path_demo.py ,会得到相对路径。
为了获取绝对路径,可调用 os.path.abspath()
os.path 中的一些方法
4、 os.path.split(path)
将路径名称分成头和尾一对。尾部永远不会带有斜杠。如果输入的路径以斜杠结尾,那么得到的空的尾部。
代码示例
环境 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 功能
本来以为已经理解了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里面的。
在包内运行文件,如果需要导入包的内容,一定要注意不可使用相对路径
SystemError: Parent module ‘’ not loaded, cannot perform relative import