模块化编程(二)

server/2024/10/18 10:28:32/

模块的导入

经常有这样一句话:“不要重复造轮子”,知道别人已经造好了轮子,并且轮子也好用,那就直接拿别人的轮子来用,此处的“模块导入”就是“拿别人的轮子过来”。前文提到模块化编程的好处之一就是“代码复用性高”。写好的模块可以被反复调用,模块的导入就是“在本模块中使用其它模块”。

写文章-CSDN创作中心icon-default.png?t=N7T8https://mp.csdn.net/mp_blog/creation/editor/140068975

import语句导入

import语句基本格式如下

import 模块名
import 模块1,模块2...    # 导入多个模块
import 模块名 as 模块别名    # 导入模块并给导入的模块取个名字

import加载的模块分为4类:

  1. 使用Python编写的 .py 文件
  2. 已被编译为共享库或DLL的C或C++扩展
  3. 一组模块的包
  4. 使用C编写并链接到Python解释器的内置模块 

通过import语句实现导入和使用模块时,本质上是使用了内置函数 __import__(),Python解释器进行执行,最终会生成一个 module类 对象,这个对象就代表了被加载的模块,且被其引用。因此,我们通过import语句导入多个模块时,本质上也就是生成多个 module类对象,而给模块起个别名本质上就是新创建一个变量引用加载的模块对象。

注意:导入多个相同模块时,只有一行语句会生效,其他的都没用。

示例代码如下

import os.pathprint(id(os.path))
print(type(os.path))

代码运行结果

1749657667760
<class 'module'>Process finished with exit code 0

 from...import导入

基本语法格式如下

form 模块名 import 成员1,成员2[,...]    #导入要用的成员1,成员2[,...]
form 模块名 import *                   #导入一个模块中所有成员

注意:尽量避免 from 模块名 import * 这种写法,因为这会导入该模块中所有不是以下划线_开头的名字全都导入当前位置。因为模块中有很多属性,很有可能导入的属性和其他属性同名,从而发生命名冲突,而且代码可读性极差。

示例代码如下

from math import piprint(pi)

代码运行结果

3.141592653589793Process finished with exit code 0

import 语句 和 form...import语句的区别 

import 导入的是模块,from...import语句导入的是模块中的函数或类。在使用import语句导入的模块时要加 模块名,而在使用 from...import语句导入时则可以直接用函数或类名。

示例代码如下

首先定义一个Calculate.py文件,在文件中输入下面代码

"""一个简单的计算器"""def add(*nums):total = 0for num in nums:total+=numprint(f"计算的总和为:{total}")return totaldef minus(a,b):print(f"{a}-{b}={a-b}")return a-bclass MyCalculate():def print_all(self,num):print(num)

再定义一个用于测试的 .py文件,输入下面代码

import Calculateprint(Calculate.add(1,2,3))
print(Calculate.minus(3,2))
------------------------------------------------------------------------
# 上面代码等价于下面代码
from Calculate import add,minusprint(add(1,2,3))
print(minus(3,2))

代码运行结果

计算的总和为:6
6
3-2=1
1Process finished with exit code 0

import加载底层原理

__import__()动态导入

import语句本质上就是调用内置函数 __import__(),可以给 __import__()动态传递不同的参数值,就能导入不同的模块。

示例代码如下

s = "math"
m = __import__(s) #导入模块math并将其引用赋给m
print(m.sqrt(9))
print(m.pi)

代码运行结果

3.0
3.141592653589793Process finished with exit code 0

注意:一般不建议使用 __import__(),因为它在Python2和Python3中有差异,可能会导致意外错误。

模块的加载问题

当导入一个模块时,模块中的代码都会被执行。不过,如果再次导入改模块,则不会再次执行。因为导入模块更多的时候需要的是模块中定义的变量、函数、对象等。因此,一个模块无论导入多少次,这个模块在整个解释器进程内有且仅有一个实例对象。

重新加载

若有时候确实需要重新加载模块,可以用:importlib.reload()方法。

示例代码如下

import Calculate
import importlibimportlib.reload(Calculate)

http://www.ppmy.cn/server/53726.html

相关文章

centos 7.9 离线环境安装GPU服务环境

文章目录 centos 7.9 离线环境安装GPU服务环境系统配置更新 gcc更新内核安装显卡驱动安装cuda安装docker 和 nvidia-container-runtime验证 centos 7.9 离线环境安装GPU服务环境 基于centos 7.9 离线安装gpu 服务基础环境&#xff0c;用于在docker 中运行算法服务 系统配置 …

Docker: 使用容器化数据库

使用容器化数据库 使用本地容器化数据库提供了灵活性和简易的设置,使您能够在不需要传统数据库安装开销的情况下,紧密模拟生产环境。Docker 简化了这一过程,只需几条命令就可以在隔离的容器中部署、管理和扩展数据库。 在本指南中,您将学习如何: 运行本地容器化数据库访…

5.How Fast Should You Be When Learning?(你应该用多快的速度学习? (二))

Are you failing to reach an ideal or you dont know what the ideal is? 你是否没有达到理想状态&#xff0c;或者不知道理想状态是什么? A lot of learing involves having a mental representation of what the ideal performance ought to be, a method or approach t…

Linux中--prefix命令使用及源码安装

1.prefix - 指定文件安装路径通常与configure搭配使用&#xff1a; 在安装源码时可使用下述命令指定源码安装路径&#xff1a; bogon:httpd-2.4.59 wancanchishenma$./configure --prefix/usr/local/apache 2.源码的安装一般由3个步骤组成&#xff1a;配置&#xff08;configur…

Spring面试题

文章目录 注解Component与Bean的区别Autowired 和 Resource 的区别是什么&#xff1f;使用方式: BeanBean 是线程安全的吗&#xff1f;Bean的作用域Bean 的生命周期了解么?1. Bean 实例化2. 属性赋值3. 初始化4. Bean 销毁 结合代码理解Bean的生命周期1. Bean 实例化2. Bean 属…

DevExpress WPF中文教程:Grid - 如何排序、分组、过滤数据(设计时)?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

恢复策略(上)-撤销事务(UNDO)、重做事务(REDO)

一、引言 利用前面所建立的冗余数据&#xff0c;即日志和数据库备份&#xff0c;要将数据库从一个不一致的错误状态恢复到一个一致性状态&#xff0c;还需要相关的恢复策略&#xff0c;不同DBMS的事务处理机制所采用的缓冲区管理策略可能不同&#xff0c;发生故障后的数据库不…

Unity之Hololens2开发MRTK Profile详解

前言 配置 MRTK 的主要方式之一是使用基础包中的配置文件。 场景中的主要 MixedRealityToolkit 对象具有活动配置文件 - 一个 ScriptableObject。 顶级 MRTK 配置配置文件包含主核心系统的每个核心的子配置文件数据,每个主核心系统都旨在配置其相应子系统的行为。 此外,这些…