首页 > 编程语言 >python调用另一个.py文件中的类和函数或直接运行另一个.py文件

python调用另一个.py文件中的类和函数或直接运行另一个.py文件

时间:2024-09-25 14:19:21浏览次数:10  
标签:文件 python py sys 文件夹 import path

同一文件夹下的调用

1.调用函数

A.py文件如下:


  1. def add(x,y):

  2. print('和为:%d'%(x+y))

在B.py文件中调用A.py的add函数如下:


  1. import A

  2. A.add(1,2)


  1. from A import add

  2. add(1,2)

2.调用类

A.py文件如下:


  1. class A:

  2. def __init__(self,xx,yy):

  3. self.x=xx

  4. self.y=yy

  5. def add(self):

  6. print("x和y的和为:%d"%(self.x+self.y))

在B.py文件中调用A.py的add函数如下:


  1. from A import A

  2. a=A(2,3)

  3. a.add()


  1. import A

  2. a=A.A(2,3)

  3. a.add()

在不同文件夹下调用

A.py文件的文件路径为:C:\AmyPython\Test1

B.py中调用A.py文件:


  1. import sys

  2. sys.path.append(r'C:\AmyPython\Test1')

  3. #python import模块时,是在sys.path里按顺序查找的。

  4. #sys.path是一个列表,里面以字符串的形式存储了许多路径。

  5. #使用A.py文件中的函数需要先将他的文件路径放到sys.path中

  6. import A

  7. a=A.A(2,3)

  8. a.add()

还有一种方法是创建 __init__.py 文件,参考文章【更为推荐,感觉比添加路径的方式更好】
如果这文件不在一个路径下面,import就比较麻烦了,需要在被import的文件路径下面新建一个__init__.py文件,光创建就行,不需要往里面添加内容。
比如被import的文件路径是…A/b.py下面,那么只要在文件夹A下面分别新建一个__init__.py文件,然后按照下面的语句引用即可:

import A.b
进一步说明

现在文件结构是这样的


  1. root

  2. |

  3. |--A文件夹

  4. | |--main.py

  5. |

  6. |--B文件夹

  7. |--b.py

现在主程序在A文件夹里,想调用B文件夹下的b.py文件,该怎么办呢?
本来以为只需要在a.py中写上:


  1. sys.path.append('../B')

  2. import b as bb

但实际会报错说 No module named ‘b’
ps. 这种直接添加相对路径的方式在Jupyter中就没有报错,不知道什么原因。
其实这个时候用 sys.path 来查看路径的话,会发现确实添加进来了,但添加进来的是一个相对路径,所以添加路径的时候相对路径的参考地址不是当前文件,而是python根目录。
在这里插入图片描述
关于这个问题,解决方法有3个:
1、添加绝对路径

sys.path.append('/home/gxp/Documents/B')

2、用拼接路径的方式添加绝对路径(本质和1相同)

sys.path.append(os.path.join(os.path.dirname(__file__),'../B'))

这里join是连接两个路径,__file__是代表当前文件,dirname返回文件夹的绝对路径。所以这里添加的路径本质上是'/home/gxp/Documents/A/../B',也就是说,sys.path.append('/home/gxp/Documents/B')sys.path.append('/home/gxp/Documents/A/../B')的效果是一样的。

3、采用相对引用或其他方法
这种做法存在不少问题,有些到最后也没整明白。
这种做法和上面说的创建 __init__.py 文件的方法似乎是一样的,但这里发现没添加这个文件似乎也正常运行了。
考虑如下文档结构,主程序为 b1.py 或者 main.py。
在这里插入图片描述
如果是main.py 的话会好说很多,因为它在根目录下,直接 import B.b就可以。
但如果是b1.py的话,可以采用相对导入的方式,可参考文章 Python的绝对引用 vs 相对引用全面讲解,但是自己在用的时候会报错,就像下面这种方式是不能正常运行的,会报错说ImportError: attempted relative import with no known parent package
在这里插入图片描述
这似乎是非常非常普遍的问题,但也似乎没有统一的解决方案。
可以参考Stackoverflow上的文章:

好像在Pycharm中间接引用就不会出问题,所以可能是VSCode的原因?
但不管怎么说间接引用其实不是一种很推荐的方式,就像全局变量一样,程序大了容易乱。
尤其是如果各个子文件夹中的模块还存在互相调用的话,那写起来真的就是乱七八糟了。
如果一定要解决的话,上面Stack Overflow第二篇文章中有一个解决方案。


  1. import sys

  2. from pathlib import Path

  3. sys.path[0] = str(Path(sys.path[0]).parent.parent)

  4. # 将工作目录改为项目根目录,这里每一个.parent就是向上翻一级,sys.path[0]就是当前目录

  5. from B.B1 import b2 as b2

  6. b2.b2()

这样一来,虽然主程序在一个子文件夹下,但工作目录却是根目录。所以可以像 main.py 那样通过 B.B1来解决。不过这种情况下如果各个子文件夹下的模块存在相互调用的话,也都需要在 import 时做好设置,也有些麻烦但也不是不可以。
所以整来整去,比较好的解决方案还是:
1、主程序不要放在子文件夹下,放在根目录下,然后用 import B.B1.b2的方式比较好。
2、如果主程序放在子文件夹下,一种方案是添加路径,这种方案的好处是可复用性好,但坏处是没有自动提示而且有不识别模块的警告;另一种方案就是把工作目录更改到根目录下,这种方案的好处是有自动提示写起来舒服,坏处是如果各个子文件夹内存在相互调用的话复用性会受影响。(自己还是更倾向于第二种方案,大多数人的程序其实也都有子文件夹内模块相互调用,其实问题不大)

运行另一个.py文件

参考文章 在一个python文件中运行另一个python文件_python调另外一个python文件-CSDN博客

同一目录下

  1. import os

  2. os.system("python filename.py")

运行

不同目录下

如果按照上面的方法会报错

error sh: /Users//Desktop/.py: Permission denied

正确方式为


  1. import os

  2. os.system('{} {}'.format('python',loc))

  3. # 或者是

  4. os.system('python {}'.format(loc))

这里的loc为字符串,用相对路径即可。
但这样并不能把运行的文件得到的变量输出出来,如果想把结果输出出来并进一步运算,参考文章,所采用的方法是


  1. # 所采用的方法如下

  2. # from 变量所在文件名 import 变量名

  3. import os

  4. # os.system('{} {}'.format('python','A/main.py'))

  5. os.system('python {}'.format('A/main.py'))

  6. from A.main import c # 如果在同一目录下则直接 from main import c 即可

  7. d = c+1

  8. print('d=',d)

标签:文件,python,py,sys,文件夹,import,path
From: https://blog.csdn.net/python_shusu_a/article/details/142487523

相关文章

  • php中使用FPDF生成PDF文件
    1.下载安装FPDF,可以在官网上下载(http://www.fpdf.org/),下载压缩包后解压,解压后的文件夹命名为“fpdf”。2.创建一个php文件和“fpdf”平级,代码如下<?phprequire('fpdf/fpdf.php');$pdf=newFPDF();$pdf->AddPage();$pdf->SetFont('Arial','B',16);$pdf->Image('......
  • module collections has no attribute Hashable PyDocx 库报错
    项目背景在测试PyDocx代码时```pythonfrompydocximportPyDocXhtml=PyDocX.to_html("test.docx")withopen("test.html",'w',encoding="utf-8")asf:f.write(html)```发生错误:Traceback(mostrecentcalllast):File"D:......
  • python 2024-9
    第一课问题a,b求最大值?分类讨论ifa>b:print("最大值=",a)else:print("最大值=",b)a,b,c求最大值?条件语句if...elif...else列表最大值?与参照物循环比较a=[1.7,1.65,1.8,1.55,1.6]#身高列表mx=0#初始化最大值forxin......
  • 《腾讯视频》qqlivebase.dll报错怎么回事,几个快速解决腾讯视频qqlivebase.dll文件丢失
    在我们日常的娱乐生活中,腾讯视频无疑是一个备受欢迎的视频播放平台。然而,当你正准备沉浸在精彩的影视内容中时,却突然遭遇qqlivebase.dll报错,这无疑会让人感到十分困扰。那么,qqlivebase.dll报错究竟是怎么回事呢?又有哪些快速解决腾讯视频qqlivebase.dll文件丢失的方法呢?......
  • 《穿越火线》无法正常运行:穿越火线audiere.dll文件丢失的原因及解决办法分享
    在众多精彩刺激的网络游戏中,《穿越火线》以其紧张激烈的战斗场景和丰富多样的玩法,吸引了无数玩家的热爱。不过有玩家在准备玩游戏时却突然发现游戏无法正常运行,提示audiere.dll文件丢失,这无疑会让人感到十分困惑。别着急,下面就让我们一起来探讨穿越火线audiere.dll文件丢失......
  • 如何修复英雄联盟常见dll错误,操作系统提示缺少英雄联盟dll文件的有效解决办法
    在众多热门游戏中,《英雄联盟》以其精彩的竞技性和丰富的玩法深受玩家喜爱。然而,当玩家准备在召唤师峡谷大显身手时,却可能遭遇因操作系统中缺少DLL文件而导致的游戏无法启动等问题,这无疑令人十分困扰。别担心,下面就为大家介绍一些有效解决操作系统中缺少英雄联盟DLL文件的办......
  • python-成绩转换/药房管理/求正整数2~n之间的完全数
    一:成绩转换题目描述输入一个百分制的成绩 t ,将其转换成对应的等级,具体转换规则如下:90∼10090∼100 为A;80∼8980∼89为B;70∼7970∼79为C;60∼6960∼69为D;0∼590∼59为E。输入格式输入数据有多组,每组占一行,由一个整数组成。输出格式对于每组输入数据,输出一行。......
  • 基于python+flask框架的老人养老社区服务平台(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着全球人口老龄化趋势的加剧,老年人口比例不断上升,如何为老年人提供全面、便捷、高效的养老服务成为社会各界关注的焦点。传统家庭养老模......
  • 基于python+flask框架的乐佳购物商城的设计与实现(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着互联网技术的飞速发展,电子商务已成为现代商业活动不可或缺的一部分,极大地改变了人们的消费习惯。乐佳购物商城的设计与实现正是在这一......
  • 基于python+flask框架的乐乐商城商品进销存管理系统(开题+程序+论文) 计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着电子商务的蓬勃发展,线上商城已成为消费者购物的重要渠道之一。乐乐商城作为新兴的电商平台,面临着日益增长的商品种类与交易量,如何高效......