网站LOGO
公爵书房 | 技术分享
页面加载中
2月24日
网站LOGO 公爵书房 | 技术分享
以指键之轻,承载知识之重
菜单
  • 公爵书房 | 技术分享
    以指键之轻,承载知识之重
    用户的头像
    首次访问
    上次留言
    累计留言
    我的等级
    我的角色
    打赏二维码
    打赏博主
    Python学习笔记(一)·基础
    点击复制本页信息
    微信扫一扫
    文章二维码
    文章图片 文章标题
    创建时间
  • 一 言
    确认删除此评论么? 确认
  • 本弹窗介绍内容来自,本网站不对其中内容负责。

    Python学习笔记(一)·基础

    公爵 · 原创 ·
    笔记 · 学习笔记python基础
    共 29094 字 · 约 24 分钟 · 130
    本文最后更新于2023年09月02日,已经过了175天没有更新,若内容或图片失效,请留言反馈
    Python 非常适合初学者用来进入计算机编程领域。Python 属于非常高级的语言,掌握了这门高级语言,就对计算机编程的核心思想——抽象有了初步理解。如果希望继续深入学习计算机编程,可以学习 Java、C、JavaScript、Lisp 等不同类型的语言,只有多掌握不同领域的语言,有比较才更有收获。
     ></cat_post_image><h2>1.1 环境准备</h2><h3>1.1.1 Python 安装</h3><p>(1)官网下载 Python</p><p>进入官网(<a target=_blank href= >

    1.1 环境准备

    1.1.1 Python 安装

    (1)官网下载 Python

    进入官网(https://www.python.org),点击 Downloads,选择要下载的版本:

     ></cat_post_image><p>(2)安装 Python</p><p>安装时注意下图勾选部分一定要勾选:</p><cat_post_image><img src= >

    (2)安装 Python

    安装时注意下图勾选部分一定要勾选:

    1.1.2 安装代码编辑器 PyCharm

    (1)官网下载 PyCharm

    进入官网(https://www.jetbrains.com/pycharm),点击 Downloads,选择要下载的版本:

     ></cat_post_image><p>(2)安装 PyCharm</p><p>设置安装路径之后,一直点 next 即可。</p><cat_post_image><img src= >

    (2)安装 PyCharm

    设置安装路径之后,一直点 next 即可。

    1.1.3 安装 Jupyter notebook

    数据分析,对我来说最好用的还是 Jupyter notebook

    • Jupyter notebook :基于 web 的交互式计算环境,可以编辑易于人们阅读的文档,用于展示数据分析的过程。
    观察一段 10 行 Python 代码,感受一下 Python 的风格:
    # 温度转换
    # TempConvert.py
    TempStr = input("请输入带有符号的温度值:")
    if TempStr[-1] in ['F','f']:
      C = (eval(TempStr[0:-1]) - 32)/1.8
      print("转换后的温度是{:.2f}C".format(C))
    elif TempStr[-1] in ['C','c']:
      F = 1.8*eval(TempStr[0:-1]) + 32
      print("转换后的温度是{:.2f}F".format(F))
    else:
      print("输入格式错误!")

    ☎️ eval()去掉参数最外侧引号并执行余下语句的函数,称为“评估函数”。

    程序的基本编写方法:IPO
    • I:Input 输入,程序的输入
    • P:Process 处理,程序的主要逻辑
    • O:Output 输出,程序的输出

    编程解决问题的步骤

    • (1)分析问题:分析问题的计算部分,想清楚
    • (2)划分边界:划分问题的功能边界,规划 IPO
    • (3)设计算法:设计问题的求解算法,关注算法
    • (4)编写程序:编写问题的计算程序,编程序
    • (5)调试测试:调试程序使正确运行,运行调试
    • (6)升级维护:适应问题的升级维护,更新完善

    1.2 第一个 Python 程序

    1.2.1 HelloWorld

    创建第一个项目 HelloWorld --> 创建文件 app.py --> 写入代码:

    print("HelloWorld")

    效果图:

     ></cat_post_image><h3>1.2.2 输入和输出</h3><h4>① 输出</h4><p>用 <code>print()</code> 在括号中加上字符串,就可以向屏幕上输出指定的文字。比如输出 <code>hello, world</code>,用代码实现如下:</p><pre><code>print('hello, world')</code></pre><p><code>print()</code> 函数也可以接受多个字符串,用逗号 “,” 隔开,就可以连成一串输出:</p><pre><code>print('The quick brown fox', 'jumps over', 'the lazy dog')</code></pre><p><code>print()</code> 会依次打印每个字符串,遇到逗号 “,” 会输出一个空格,因此,输出的字符串是这样拼起来的:</p><p>?> The quick brown fox jumps over the lazy dog</p><p><code>print()</code> 也可以打印整数,或者计算结果:</p><pre><code>print(300)
print('100 + 200 = ',100 + 200) # 输出 100 + 200 = 300</code></pre><p>!> 注意,对于 <code>100 + 200</code>,Python 解释器自动计算出结果 <code>300</code>,但是,<code>'100 + 200 ='</code> 是字符串而非数学公式,Python 把它视为字符串</p><h4>② 输入</h4><p>Python 提供了一个 <code>input()</code>,可以让用户输入字符串,并存放到一个变量里。比如输入用户的名字:</p><pre><code>print('Input your name: ')
name = input()
print('Hello! ',name)</code></pre><cat_post_image><img src= ></cat_post_image><ul><li><strong>删除</strong></li></ul><p>要删除 list 末尾的元素,用 <code>pop()</code> 方法:</p><pre><code>classmates.pop()</code></pre><p>要删除指定位置的元素,用 <code>pop(i)</code> 方法,其中 <code>i</code> 是索引位置:</p><pre><code>classmates.pop(1)</code></pre><p>效果:</p><cat_post_image><img src= >
    • 删除

    要删除 list 末尾的元素,用 pop() 方法:

    classmates.pop()

    要删除指定位置的元素,用 pop(i) 方法,其中 i 是索引位置:

    classmates.pop(1)

    效果:

    • 替换

    要把某个元素替换成别的元素,可以直接赋值给对应的索引位置:

    classmates[1] = 'Oliver'
    Ⅱ 不可变有序列表 - 元组 tuple ( )

    另一种有序列表叫元组:tuple。tuple 和 list 非常类似,但是 tuple 一旦初始化就不能修改,比如同样是列出同学的名字:

    classmates = ('Michael', 'Bob', 'Tracy')

    现在,classmates 这个 tuple 不能变了,它也没有 append(),insert() 这样的方法。其他获取元素的方法和 list 是一样的,你可以正常地使用 classmates[0]classmates[-1],但不能赋值成另外的元素。

    !> 不可变的 tuple 有什么意义?因为 tuple 不可变,所以代码更安全。如果可能,能用 tuple 代替 list 就尽量用 tuple。

    ? tuple 的陷阱:当你定义一个 tuple 时,在定义的时候,tuple 的元素就必须被确定下来,比如:

    t = (1, 2)
    print(t) # (1, 2)

    如果要定义一个空的 tuple,可以写成 ()

    t = ()
    print(t) # ()

    但是,要定义一个只有 1 个元素的 tuple,如果你这么定义:

    t = (1)
    print(t) # 1

    定义的不是 tuple,是 1 这个数!这是因为括号 () 既可以表示 tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python 规定,这种情况下,按小括号进行计算,计算结果自然是 1

    所以,只有 1 个元素的 tuple 定义时必须加一个逗号,,来消除歧义

    t = (1,)
    print(t) # (1,)

    ?> Python 在显示只有 1 个元素的 tuple 时,也会加一个逗 ,,以免你误解成数学计算意义上的括号。

    最后来看一个 “可变的” tuple

    t = ('a', 'b', ['A', 'B'])
    t[2][0] = 'X'
    t[2][1] = 'Y'
    print(t) # ('a', 'b', ['X', 'Y'])

    这个 tuple 定义的时候有 3 个元素,分别是'a''b'和一个 list。不是说 tuple 一旦定义后就不可变了吗?怎么后来又变了?

    别急,我们先看看定义的时候 tuple 包含的 3 个元素:

     ></cat_post_image><p>当我们把 list 的元素 <code>'A'</code> 和 <code>'B'</code> 修改为 <code>'X'</code> 和 <code>'Y'</code> 后,tuple 变为:</p><cat_post_image><img src= >

    当我们把 list 的元素 'A''B' 修改为 'X''Y' 后,tuple 变为:

    表面上看,tuple 的元素确实变了,但其实变的不是 tuple 的元素,而是 list 的元素。tuple 一开始指向的 list 并没有改成别的 list,所以,⭐ tuple 所谓的 “不变” 是说,tuple 的每个元素,指向永远不变。即指向 'a',就不能改成指向 'b',指向一个 list,就不能改成指向其他对象,但指向的这个 list 本身是可变的!

    理解了 “指向不变” 后,要创建一个内容也不变的 tuple 怎么做?那就必须保证 tuple 的每一个元素本身也不能变。

    ⑦ 字典

    Ⅰ dict(key - value)

    Python 内置了字典:dict 的支持,dict 全称 dictionary,在其他语言中也称为 map,使用键 - 值(key - value)存储,具有极快的查找速度。

    • 创建

    示例代码:学生姓名和成绩

    d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
    print(d) # {'Michael': 95, 'Bob': 75, 'Tracy': 85}
    print(d['Michael']) # 95
    
    print(d[0]) # KeyError: 0

    为什么 dict 查找速度这么快?因为 dict 的实现原理和查字典是一样的。假设字典包含了 1 万个汉字,我们要查某一个字,一个办法是把字典从第一页往后翻,直到找到我们想要的字为止,这种方法就是在 list 中查找元素的方法,list 越大,查找越慢。

    第二种方法是先在字典的索引表里(比如部首表)查这个字对应的页码,然后直接翻到该页,找到这个字。无论找哪个字,这种查找速度都非常快,不会随着字典大小的增加而变慢。

    dict 就是第二种实现方式,给定一个名字,比如'Michael',dict 在内部就可以直接计算出 Michael 对应的存放成绩的 “页码”,也就是 95 这个数字存放的内存地址,直接取出来,所以速度非常快。

    把数据放入 dict 的方法,除了初始化时指定外,还可以通过 key 放入:

    d['Adam'] = 67
    print(d['Adam']) # 67
    print(d) # {'Michael': 95, 'Bob': 75, 'Tracy': 85, 'Adam': 67}
    • 判断 value 是否存在

    由于一个 key 只能对应一个 value,所以,多次对一个 key 放入 value,后面的值会把前面的值冲掉:

    d['Adam'] = 67
    print(d['Adam']) # 67
    d['Adam'] = 97
    print(d['Adam']) # 97

    如果 key 不存在,dict 就会报错:KeyError

     ></cat_post_image><p>要避免 key 不存在的错误,有两种办法,一是通过<code>in</code>判断 key 是否存在:</p><pre><code>print('Thomas' in d) # False</code></pre><p>二是通过 dict 提供的 <code>get()</code> 方法,如果 key 不存在,可以返回 <code>None</code>,或者自己指定的 value:</p><pre><code>print(d.get('Thomas'))  # None
print(d.get('Thomas', -1))  # -1</code></pre><ul><li><strong>删除</strong></li></ul><p>要删除一个 key,用 <code>pop(key)</code> 方法,对应的 value 也会从 dict 中删除:</p><pre><code>d.pop('Bob')</code></pre><p>!> 请务必注意,dict 内部存放的顺序和 key 放入的顺序是没有关系的。</p><p>⭐ 和 list 比较,dict 有以下几个特点:</p><ul><li>查找和插入的速度极快,不会随着 key 的增加而变慢;</li><li>需要占用大量的内存,内存浪费多。</li></ul><p>而 list 相反:</p><ul><li>查找和插入的时间随着元素的增加而增加;</li><li>占用空间小,浪费内存很少。</li></ul><p>所以,dict 是用空间来换取时间的一种方法。</p><p>dict 可以用在需要高速查找的很多地方,在 Python 代码中几乎无处不在,正确使用 dict 非常重要,需要牢记的第一条就是 dict 的 key 必须是<strong>不可变对象</strong>。</p><p>这是因为 dict 根据 key 来计算 value 的存储位置,如果每次计算相同的 key 得出的结果不同,那 dict 内部就完全混乱了。这个通过 key 计算位置的算法称为哈希算法(Hash)。</p><p>要保证 hash 的正确性,作为 key 的对象就不能变。在 Python 中,字符串、整数等都是不可变的,因此,可以放心地作为 key。而 list 是可变的,就不能作为 key:</p><cat_post_image><img src= ></cat_post_image><p>当我们调用 <code>a.replace('a', 'A')</code> 时,实际上调用方法 <code>replace</code> 是作用在字符串对象 <code>'abc'</code> 上的,而这个方法虽然名字叫 <code>replace</code>,但却没有改变字符串 <code>'abc'</code> 的内容。相反,<code>replace</code> 方法创建了一个新字符串 <code>'Abc'</code> 并返回,如果我们用变量 <code>b</code> 指向该新字符串,就容易理解了,变量 <code>a</code> 仍指向原有的字符串 <code>'abc'</code>,但变量 <code>b</code> 却指向新字符串 <code>'Abc'</code> 了:</p><cat_post_image><img src= >

    当我们调用 a.replace('a', 'A') 时,实际上调用方法 replace 是作用在字符串对象 'abc' 上的,而这个方法虽然名字叫 replace,但却没有改变字符串 'abc' 的内容。相反,replace 方法创建了一个新字符串 'Abc' 并返回,如果我们用变量 b 指向该新字符串,就容易理解了,变量 a 仍指向原有的字符串 'abc',但变量 b 却指向新字符串 'Abc' 了:

    所以,对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容。相反,这些方法会创建新的对象并返回,这样,就保证了不可变对象本身永远是不可变的。

    !> 小结

    • 使用 key - value 存储结构的 dict 在 Python 中非常有用,选择不可变对象作为 key 很重要,最常用的 key 是字符串。
    • tuple 虽然是不变对象,但试试把(1, 2, 3)(1, [2, 3])放入 dict 或 set 中,就会有新发现。

    1.3.3 变量与常量

    ① 变量

    变量是用来保存和表示数据的占位符号。变量采用标识符(名字)来表示,关联标识符的过程叫命名。比如实例 1:温度转换中的 TempStr 就是变量名字。

    命名规则:大小写字母、数字、下划线_和汉字等字符及组合,且不能用数字开头

    如:TempStr,Python\_Great,这是门Python好课

    ? 注意点:大小写敏感、首字符不能是数字、不与保留字相同。

    ⛳️ 拓展:保留字

    保留字:被编程语言内部定义并保留使用的标识符。

    • Python 语言有 33 个保留字(也叫关键字),比如:if、elif、else、in
    • 保留字是编程语言的基本单词,大小写敏感,比如:if 是保留字,If 是变量

    保留字看下表:

     ></cat_post_image><p>在 Python 中,等号 <code>=</code> 是赋值符号,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,例如:</p><pre><code>a = 123 # a是整数
print(a)
a = 'ABC' # a变为字符串
print(a)
a = True # a是一个布尔值True
print(a)</code></pre><p>? 这种变量本身类型不固定的语言称之为 <strong>动态语言 (Python、......)</strong>,与之对应的是 <strong>静态语言(Java、C++、......)</strong>。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。</p><p>例如 Java 是静态语言,赋值语句如下(// 表示注释):</p><pre><code>int a = 123; // a是整数类型变量
a = "ABC"; // 错误:不能把字符串赋给整型变量</code></pre><p>和静态语言相比,动态语言更灵活,就是这个原因。</p><p>请不要把赋值语句的等号等同于数学的等号。比如下面的代码:</p><pre><code>x = 10
x = x + 2</code></pre><p>如果从数学上理解 <code>x = x + 2</code> 那无论如何是不成立的,在程序中,赋值语句先计算右侧的表达式 <code>x + 2</code>,得到结果 <code>12</code>,再赋给变量 <code>x</code>。由于 <code>x</code> 之前的值是 <code>10</code>,重新赋值后,<code>x</code> 的值变成 <code>12</code>。</p><p>最后,理解变量在计算机内存中的表示也非常重要。当我们写:</p><pre><code>a = 'ABC'</code></pre><p>时,Python 解释器干了两件事情:</p><ul><li>在内存中创建了一个 <code>'ABC'</code> 的字符串;</li><li>在内存中创建了一个名为 <code>a</code> 的变量,并把它指向 <code>'ABC'</code>。</li></ul><p>? 也可以把一个变量 <code>a</code> 赋值给另一个变量 <code>b</code>,这个操作实际上是把变量 <code>b</code> 指向变量 <code>a</code> 所指向的数据,例如下面的代码:</p><pre><code>a = 'ABC'
b = a
a = 'XYZ'
print(b) # 输出 ABC</code></pre><p>最后一行打印出变量 <code>b</code> 的内容到底是<code>'ABC'</code>呢还是<code>'XYZ'</code>?如果从数学意义上理解,就会错误地得出 <code>b</code> 和 <code>a</code> 相同,也应该是<code>'XYZ'</code>,但实际上 <code>b</code> 的值是 <code>'ABC'</code>,让我们一行一行地执行代码,就可以看到到底发生了什么事:</p><ul><li><p>执行<code>a = 'ABC'</code>,解释器创建了字符串<code>'ABC'</code>和变量<code>a</code>,并把<code>a</code>指向<code>'ABC'</code>:</p><cat_post_image><span data-fancybox= ></cat_post_image></li><li><p>执行<code>b = a</code>,解释器创建了变量<code>b</code>,并把<code>b</code>指向<code>a</code>指向的字符串<code>'ABC'</code>:</p><cat_post_image><img src= >
  • 执行b = a,解释器创建了变量b,并把b指向a指向的字符串'ABC'

  • 执行a = 'XYZ',解释器创建了字符串'XYZ',并把a的指向改为'XYZ',但b并没有更改:

     ></cat_post_image></li><li>所以,最后打印变量<code>b</code>的结果自然是<code>'ABC'</code>了。</li></ul><h4>② 常量</h4><p>所谓常量就是不能变的变量,比如常用的数学常数 π 就是一个常量:</p><pre><code>PI = 3.14159265359</code></pre><p>在 Python 中,通常用<code>全部大写</code>的变量名表示常量。</p><p>但事实上 <code>PI</code> 仍然是一个变量,Python 根本没有任何机制保证 <code>PI</code> 不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量 <code>PI</code> 的值,也没人能拦住你。</p><h3>1.3.4 字符串和编码</h3><h4>① 字符串编码问题</h4><p>我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。</p><p>因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用 8 个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是 255(二进制 11111111 = 十进制 255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是<code>65535</code>,4 个字节可以表示的最大整数是<code>4294967295</code>。</p><p>由于计算机是美国人发明的,因此,最早只有 127 个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为<code>ASCII</code>编码,比如大写字母<code>A</code>的编码是<code>65</code>,小写字母<code>z</code>的编码是<code>122</code>。</p><p>但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和 ASCII 编码冲突,所以,中国制定了<code>GB2312</code>编码,用来把中文编进去。</p><p>你可以想得到的是,全世界有上百种语言,日本把日文编到<code>Shift_JIS</code>里,韩国把韩文编到<code>Euc-kr</code>里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。</p><cat_post_image><img src= >
  • 所以,最后打印变量b的结果自然是'ABC'了。
  • ② 常量

    所谓常量就是不能变的变量,比如常用的数学常数 π 就是一个常量:

    PI = 3.14159265359

    在 Python 中,通常用全部大写的变量名表示常量。

    但事实上 PI 仍然是一个变量,Python 根本没有任何机制保证 PI 不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量 PI 的值,也没人能拦住你。

    1.3.4 字符串和编码

    ① 字符串编码问题

    我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。

    因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用 8 个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是 255(二进制 11111111 = 十进制 255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4 个字节可以表示的最大整数是4294967295

    由于计算机是美国人发明的,因此,最早只有 127 个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母A的编码是65,小写字母z的编码是122

    但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和 ASCII 编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

    你可以想得到的是,全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。

    因此,Unicode 应运而生。Unicode 把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

    Unicode 标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要 4 个字节)。现代操作系统和大多数编程语言都直接支持 Unicode。

    ? 现在,捋一捋 ASCII 编码和 Unicode 编码的区别:ASCII 编码是 1 个字节,而 Unicode 编码通常是 2 个字节。

    • 字母A用 ASCII 编码是十进制的65,二进制的01000001
    • 字符0用 ASCII 编码是十进制的48,二进制的00110000,注意字符'0'和整数0是不同的;
    • 汉字已经超出了 ASCII 编码的范围,用 Unicode 编码是十进制的20013,二进制的01001110 00101101

    你可以猜测,如果把 ASCII 编码的A用 Unicode 编码,只需要在前面补 0 就可以,因此,A的 Unicode 编码是00000000 01000001

    新的问题又出现了:如果统一成 Unicode 编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用 Unicode 编码比 ASCII 编码需要多一倍存储空间,在存储和传输上就十分不划算。

    所以,本着节约的精神,又出现了把 Unicode 编码转化为 “可变长编码” 的UTF-8编码。UTF-8 编码把一个 Unicode 字符根据不同的数字大小编码成 1-6 个字节,常用的英文字母被编码成 1 个字节,汉字通常是 3 个字节,只有很生僻的字符才会被编码成 4-6 个字节。如果你要传输的文本包含大量英文字符,用 UTF-8 编码就能节省空间:

     ></cat_post_image><p>从上面的表格还可以发现,UTF-8 编码有一个额外的好处,就是 ASCII 编码实际上可以被看成是 UTF-8 编码的一部分,所以,大量只支持 ASCII 编码的历史遗留软件可以在 UTF-8 编码下继续工作。</p><p>搞清楚了 ASCII、Unicode 和 UTF-8 的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:</p><p>? <strong>在计算机内存中,统一使用 Unicode 编码,当需要保存到硬盘或者需要传输的时候,就转换为 UTF-8 编码。</strong></p><p>用记事本编辑的时候,从文件读取的 UTF-8 字符被转换为 Unicode 字符到内存里,编辑完成后,保存的时候再把 Unicode 转换为 UTF-8 保存到文件:</p><cat_post_image><img src= >

    从上面的表格还可以发现,UTF-8 编码有一个额外的好处,就是 ASCII 编码实际上可以被看成是 UTF-8 编码的一部分,所以,大量只支持 ASCII 编码的历史遗留软件可以在 UTF-8 编码下继续工作。

    搞清楚了 ASCII、Unicode 和 UTF-8 的关系,我们就可以总结一下现在计算机系统通用的字符编码工作方式:

    ? 在计算机内存中,统一使用 Unicode 编码,当需要保存到硬盘或者需要传输的时候,就转换为 UTF-8 编码。

    用记事本编辑的时候,从文件读取的 UTF-8 字符被转换为 Unicode 字符到内存里,编辑完成后,保存的时候再把 Unicode 转换为 UTF-8 保存到文件:

    浏览网页的时候,服务器会把动态生成的 Unicode 内容转换为 UTF-8 再传输到浏览器:

     ></cat_post_image><p>所以你看到很多网页的源码上会有类似 <code><meta charset="UTF-8" /></code> 的信息,表示该网页正是用的 UTF-8 编码。</p><h4>② 字符串详解</h4><p>搞清楚了令人头疼的字符编码问题后,我们再来研究 Python 的字符串。</p><p>在最新的 Python 3 版本中,字符串是以 Unicode 编码的,也就是说,<strong>Python 的字符串支持多语言</strong>,例如:</p><pre><code>print('包含中文的str')
# 输出:包含中文的str</code></pre><p>对于单个字符的编码,Python 提供了<code>ord()</code>函数获取字符的整数表示,<code>chr()</code>函数把编码转换为对应的字符:</p><pre><code>ord('A') # 65
ord('中') # 20013
chr(66) # 'B'
chr(25991) # '文'</code></pre><p>如果知道字符的整数编码,还可以用十六进制这么写<code>str</code>:</p><pre><code>print('\u4e2d\u6587') # 中文</code></pre><p>两种写法完全是等价的。</p><p>由于 Python 的字符串类型是<code>str</code>,在内存中以 Unicode 表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把<code>str</code>变为以字节为单位的<code>bytes</code>。</p><p>Python 对<code>bytes</code>类型的数据用带<code>b</code>前缀的单引号或双引号表示:</p><pre><code>x = b'ABC'</code></pre><p>要注意区分<code>'ABC'</code>和<code>b'ABC'</code>,前者是<code>str</code>,后者虽然内容显示得和前者一样,但<code>bytes</code>的每个字符都只占用一个字节。</p><p>以 Unicode 表示的<code>str</code>通过<code>encode()</code>方法可以编码为指定的<code>bytes</code>,例如:</p><pre><code>print('ABC'.encode('ascii')) # b'ABC'
print('中文'.encode('utf-8')) # b'\xe4\xb8\xad\xe6\x96\x87'</code></pre><p>纯英文的<code>str</code>可以用<code>ASCII</code>编码为<code>bytes</code>,内容是一样的,含有中文的<code>str</code>可以用<code>UTF-8</code>编码为<code>bytes</code>。<strong>含有中文的<code>str</code>无法用<code>ASCII</code>编码</strong>,因为中文编码的范围超过了<code>ASCII</code>编码的范围,Python 会报错。</p><p>反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是<code>bytes</code>。要把<code>bytes</code>变为<code>str</code>,就需要用<code>decode()</code>方法:</p><pre><code>print(b'ABC'.decode('ascii'))
print(b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))</code></pre><p>如果<code>bytes</code>中包含无法解码的字节,<code>decode()</code>方法会报错:</p><cat_post_image><span data-fancybox= ></cat_post_image><p>如果<code>bytes</code>中只有一小部分无效的字节,可以传入<code>errors='ignore'</code>忽略错误的字节:</p><cat_post_image><img src= >

    如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:

    要计算str包含多少个字符,可以用len()函数:

    print(len('ABC')) # 3
    print(len('中文')) # 2

    len()函数计算的是str的字符数,如果换成byteslen()函数就计算字节数:

    print(len(b'ABC')) # 3
    print(len(b'\xe4\xb8\xad\xe6\x96\x87')) # 6
    print(len('中文'.encode('utf-8'))) # 6

    可见,1 个中文字符经过 UTF-8 编码后通常会占用 3 个字节,而 1 个英文字符只占用 1 个字节。

    ? 在操作字符串时,我们经常遇到strbytes的互相转换。为了避免乱码问题,应当始终坚持使用 UTF-8 编码对strbytes进行转换。

    由于 Python 源代码也是一个文本文件,所以,当你的源代码中包含中文的时候,在保存源代码时,就需要务必指定保存为 UTF-8 编码。当 Python 解释器读取源代码时,为了让它按 UTF-8 编码读取,我们通常在文件开头写上这两行:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-

    第一行注释是为了告诉 Linux/OS X 系统,这是一个 Python 可执行程序,Windows 系统会忽略这个注释;

    第二行注释是为了告诉 Python 解释器,按照 UTF-8 编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。

    ③ 格式化

    最后一个常见的问题是如何输出格式化的字符串。我们经常会输出类似'亲爱的 xxx 你好!你 xx 月的话费是 xx,余额是 xx'之类的字符串,而 xxx 的内容都是根据变量变化的,所以,需要一种简便的格式化字符串的方式。

     ></cat_post_image><p>在 Python 中,采用的格式化方式和 C 语言是一致的,用<code>%</code>实现,举例如下:</p><pre><code>print('Hello, %s' % 'world') # Hello, world
print('Hello, %s, you have %d money' %('WuGenQiang',100))
# Hello, WuGenQiang, you have 100 money</code></pre><p>你可能猜到了,<code>%</code>运算符就是用来格式化字符串的。在字符串内部,<code>%s</code>表示用字符串替换,<code>%d</code>表示用整数替换,有几个<code>%?</code>占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个<code>%?</code>,括号可以省略。</p><p>常见的占位符有:</p><cat_post_image><img src=廖雪峰 - Python 3.x - Python 基础
  • Python 语言程序设计 - 北京理工大学
  • 声明:本文由 公爵(博主)原创,依据 CC-BY-NC-SA 4.0 许可协议 授权,转载请注明出处。

    还没有人喜爱这篇文章呢

    发一条! 发一条!
    博客logo 公爵书房 | 技术分享 以指键之轻,承载知识之重 51统计 百度统计
    MOEICP 萌ICP备20226257号 ICP 赣ICP备2022001242号-1 ICP 闽公网安备35020502000606号 又拍云 本站由又拍云提供CDN加速/云存储服务

    🕛

    本站已运行 2 年 35 天 20 小时 53 分

    🌳

    自豪地使用 Typecho 建站,并搭配 MyLife 主题
    公爵书房 | 技术分享. © 2022 ~ 2024.
    网站logo

    公爵书房 | 技术分享 以指键之轻,承载知识之重
     
     
     
     
    壁纸