Python进阶知识(一)

这篇具有很好参考价值的文章主要介绍了Python进阶知识(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.简单模块化

最简单的模块化方式,你可以把函数、类、常量拆分到不同的文件,把它们放在同一个文 件夹,然后使用 from your_file import function_name, class_name 的方式调 用。之后,这些函数和类就可以在文件内直接使用了。

1 # utils.py
2
3 def get_sum(a, b):
4 return a + b
# class_utils.py
class Encoder(object):
    def encode(self, s):
        return s[::-1]
class Decoder(object):
    def decode(self, s):
        return ''.join(reversed(list(s)))
1 # main.py 2
3 from utils import get_sum
4 from class_utils import *
5
6 print(get_sum(1, 2)) 7
8 encoder = Encoder()
9 decoder = Decoder()
10
11 print(encoder.encode('abcde'))
12 print(decoder.decode('edcba'))
13
14 ########## 输出 ########## 15
16 3
17 edcba
18 abcde

看看上面的示例代码,get_sum() 函数定义在 utils.py,Encoder 和 Decoder 类则在 class_utils.py,我们在 main 函数直接调用 from import ,就可以将我们需要的东西 import 过来。

但是这样就行了吗,不,慢慢的你会发现所有的文件都堆在一个文件夹下面也不是办法

然后就必须创建一些子文件夹

1 # utils/utils.py
2
3 def get_sum(a, b):
4     return a + b
# utils/class_utils.py
class Encoder(object):
    def encode(self, s):
        return s[::-1]
class Decoder(object):
    def decode(self, s):
        return ''.join(reversed(list(s)))
1 # src/sub_main.py 2
3 import sys
4 sys.path.append("..")
5
6 from utils.class_utils import * 7
8 encoder = Encoder()
9 decoder = Decoder()
而这一次,我们的文件结构是下面这样的:
1.
2 ├── utils
3 │ ├── utils.py
4 │ └── class_utils.py 5 ├── src
6 │ └── sub_main.py
7 └── main.py

很容易看出,main.py 调用子目录的模块时,只需要使用 . 代替 / 来表示子目录,utils.utils 表示 utils 子文件夹下的 utils.py 模块就行。

那如果我们想调用上层目录呢?注意,sys.path.append(“…”) 表示将当前程序所在位置 向上提了一级,之后就能调用 utils 的模块了。

2.项目模块化

核心就是 以项目的根目录作为最基本的目录,所有的模块调用,都要通过根目录 一层层向下索引的方式来 import

明白了这一点后,这次我们使用 PyCharm 来创建一个项目。这个项目结构如下所示:

2 ├── proto
3 │    ├── mat.py
  ├── utils
5 │    └── mat_mul.py
6 └── src
7      └── main.py
# proto/mat.py
class Matrix(object):
    def __init__(self, data):
        self.data = data
        self.n = len(data)
        self.m = len(data[0])
# utils/mat_mul.py
from proto.mat import Matrix
def mat_mul(matrix_1: Matrix, matrix_2: Matrix):
    assert matrix_1.m == matrix_2.n
    n, m, s = matrix_1.n, matrix_1.m, matrix_2.m
    result = [[0 for _ in range(n)] for _ in range(s)]
    for i in range(n):
        for j in range(s):
            for k in range(m):
                result[i][k] += matrix_1.data[i][j] * matrix_2.data[j][k]
    return Matrix(result)
1 # src/main.py 2
3 from proto.mat import Matrix
4 from utils.mat_mul import mat_mul
5 6
7 a = Matrix([[1, 2], [3, 4]])
8 b = Matrix([[5, 6], [7, 8]])
9
10 print(mat_mul(a, b).data)

请注意 utils/mat_mul.py,你会发现,它 import Matrix 的方式是from proto.mat。这种做法,直接从项目根目录中导入,并依次向下导入 模块 mat.py 中的 Matrix,而不是使用 … 导入上一级文件夹。

是不是很简单呢?对于接下来的所有项目,你都能直接使用 Pycharm 来构建。把不同模块放 在不同子文件夹里,跨模块调用则是从顶层直接索引,一步到位,非常方便。

在Python中,if __name__ == '__main__' 是一个常见的代码块,用于确定当前模块是作为主程序运行还是作为导入模块使用。

当一个Python脚本文件被直接执行时,Python解释器会将该脚本文件的__name__属性设置为'__main__',这是Python中的内置属性。如果一个模块是作为主程序运行,那么__name__属性的值就是'__main__'

因此,当你使用 if __name__ == '__main__' 来判断时,它实际上检查的是当前模块是否是作为主程序执行的。如果是主程序执行,该条件语句块中的代码将被执行;如果是作为导入模块使用,该条件语句块中的代码将被跳过。

这个机制通常用于模块的测试和调试。通过将一些测试代码放在if __name__ == '__main__'块中,你可以在模块被导入时避免这些测试代码被执行,只有在直接运行该模块时才会执行这些测试代码。

3.浅拷贝和深度拷贝

在 Python 中,浅拷贝(shallow copy)和深拷贝(deep copy)是用于创建对象副本的两种不同方式。

浅拷贝是指创建一个新对象,该对象的内容是原始对象中元素的引用。换句话说,浅拷贝创建了一个新的对象,但该对象中的元素仍然与原始对象共享。修改原始对象中的元素也会反映在浅拷贝对象中。在 Python 中,可以使用 copy 模块的 copy() 函数或者对象的 copy() 方法进行浅拷贝。

示例代码:

pythonCopy code
import copy

list1 = [1, 2, 3, [4, 5]]
list2 = copy.copy(list1)

# 修改原始对象
list1[3].append(6)

print(list1)  # 输出: [1, 2, 3, [4, 5, 6]]
print(list2)  # 输出: [1, 2, 3, [4, 5, 6]]

深拷贝是指创建一个新对象,该对象及其内容都是原始对象的完全独立副本。换句话说,深拷贝创建了一个与原始对象完全无关的新对象。修改原始对象中的元素不会影响深拷贝对象。在 Python 中,可以使用 copy 模块的 deepcopy() 函数或者对象的 deepcopy() 方法进行深拷贝。

示例代码:

pythonCopy code
import copy

list1 = [1, 2, 3, [4, 5]]
list2 = copy.deepcopy(list1)

# 修改原始对象
list1[3].append(6)

print(list1)  # 输出: [1, 2, 3, [4, 5, 6]]
print(list2)  # 输出: [1, 2, 3, [4, 5]]

浅拷贝只复制了对象的引用,而深拷贝创建了一个完全独立的对象副本。选择使用浅拷贝还是深拷贝取决于你的需求和数据结构的复杂性。

4.值传递和引用传递

在 Python 中,参数传递方式既不是纯粹的值传递(pass by value)也不是纯粹的引用传递(pass by reference),而是通过对象的引用进行传递,通常称为对象的传递(pass by object)。

当你将一个对象作为参数传递给函数或赋值给另一个变量时,实际上是将该对象的引用传递给了函数或变量。这意味着函数或变量可以通过引用访问和修改原始对象。

值传递是指将对象的副本传递给函数或变量,函数或变量对副本的修改不会影响原始对象。对于不可变对象(例如数字、字符串和元组),参数传递是值传递的。这是因为不可变对象无法修改,每次传递时都会创建一个新的对象副本。

示例代码:

pythonCopy code
def update_value(num):
    num += 1
    print(num)

value = 10
update_value(value)
print(value)  # 输出: 10

引用传递是指将对象的引用传递给函数或变量,函数或变量可以通过引用修改原始对象。对于可变对象(例如列表、字典和集合),参数传递是引用传递的。

示例代码:

pythonCopy code
def update_list(lst):
    lst.append(4)
    print(lst)

my_list = [1, 2, 3]
update_list(my_list)
print(my_list)  # 输出: [1, 2, 3, 4]

需要注意的是,虽然对于可变对象来说是引用传递,但如果在函数内部重新分配对象或修改引用,不会影响原始对象或变量。

示例代码:

pythonCopy code
def update_list(lst):
    lst = [4, 5, 6]  # 在函数内部重新分配对象
    print(lst)

my_list = [1, 2, 3]
update_list(my_list)
print(my_list)  # 输出: [1, 2, 3]

综上所述,Python 中的参数传递是通过对象的引用进行的,对于不可变对象是值传递,对于可变对象是引用传递。这种特性使得在函数中修改可变对象成为可能,但需要注意对象重新分配和引用修改的影响文章来源地址https://www.toymoban.com/news/detail-496492.html

到了这里,关于Python进阶知识(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python面向对象编程,实现模块化开发

    面向对象编程(Object Oriented Programming,OOP)是一种编程范式,它将真实世界中的事物抽象成程序中的对象,并通过对象之间的相互作用来完成程序的逻辑。 封装 (Encapsulation) 封装是指把数据和行为结合成一个相对独立的整体,防止程序中其他部分直接访问或修改这个整体,而

    2024年02月05日
    浏览(142)
  • Python中的模块化编程与软件架构设计

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在软件开发中,模块化编程和良好的软件架构设计是确保项目可维护性、可扩展性和可重用性的关键。Python作为一种灵活且功能丰富的编程语

    2024年04月29日
    浏览(52)
  • 什么是模块化?为什么要进行模块化开发?

    模块化是一种软件开发的设计模式,它将一个大型的软件系统划分成多个独立的模块,每个模块都有自己的功能和接口,并且能够与其他模块独立地工作。  先来一段八股文 模块化开发可以带来以下好处: 提高代码的复用性:模块化可以将代码划分成可重用的部分,降低代

    2023年04月12日
    浏览(59)
  • 23年,我又学习了一次amd模块化,模块化思想

    src/view1/index.html src/view1/main.js plugins/module.js 源码链接: https://gitee.com/littleboyck/front/tree/master/front-module 联系方式:QQ: 1187253007

    2024年02月07日
    浏览(58)
  • 【前端模块化】JS模块化思想以及相关规范(CommonJS、ES module)

    1.模块化概念 随着前端应用日趋复杂,项目代码也大量膨胀,模块化就是一种最主流的代码组织方式, 一个模块就是一个实现特定功能的文件 ,它通过把我们的复杂代码按照功能的不同,划分为不同的模块单独维护的这种方式,去提高我们的开发效率,降低维护成本。要用

    2024年02月01日
    浏览(63)
  • Vuex模块化管理

    如果你的项目是一个小型项目,就用不着使用模块化; 但是,如果你参与的项目是一个中大型项目,那Vuex模块化,必不可少,否则整个文件很臃肿,也很难管理。 通过模块化管理:各自模块下都有自己的state及方法,各自模块管理自己的数据,这样不容易造成混乱。 第一步

    2024年02月15日
    浏览(46)
  • webpack(一)模块化

    阶段一:基于文件的划分模块方式 概念 :将每个功能和相关数据状态分别放在单独的文件里 约定每一个文件就是一个单独的模块,使用每个模块,直接调用这个模块的成员 缺点 :所有的成员都可以在模块外被访问和修改(所有的模块都是直接在全局工作,没有【私有空间

    2024年02月11日
    浏览(43)
  • js 模块化

    模块化主要是用来抽离公共代码,隔离作用域,避免变量冲突等。 模块化的整个发展历史如下: IIFE :使用自执行函数来编写模块化,特点:在一个单独的函数作用域中执行代码,避免代码冲突。 AMD :使用 require 来编写模块化,特点:依赖必须提前声明好。 CMD :使用 seaJS

    2024年02月14日
    浏览(52)
  • OpenHarmony模块化编译

    OpenHarmony版本:OpenHarmony 4.0 Release 编译环境:WSL2 Ubuntu 18.04 平台设备:RK3568 OpenHarmony 代码构建有build.sh和hb两种方式: 下拉的4.0代码无法直接使用hb命令 可参考搭建开发环境-安装编译工具 进行hb安装和环境配置。 在源码目录执行\\\"hb help\\\",界面打印以下信息即表示安装成功。 注

    2024年02月03日
    浏览(43)
  • Rust的模块化

    Rust的模块化要从Rust的入口文件谈起。 Rust的程序的入口文件有两个 如果程序类型是可执行应用,入口文件是main.rs; 如果程序类型是库,入口文件是lib.rs; 入口文件中,必须声明本地模块,否则编译器在编译过程中,会报该模块不存在的错误。这个规则,在其它程序的编译

    2024年02月09日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包