Python tutorial文档笔记

三、Python速览


  • 原始字符串

print(r'C:\some\name')
原始字符串还有一个微妙的限制:一个原始字符串不能以奇数个 \ 字符结束

  • 以下切片操作会返回列表的浅拷贝

squares[:]

  • append() 方法

可以在列表末尾添加新元素

四、其他流程控制工具


  • 循环
for i in range(5):
    print(i)
a = ['Mary', 'had', 'a', 'little', 'lamb']
for i in range(len(a)):
    print(i, a[i])
  • pass 语句

  • match 语句

match status:
        case 400:
            return "Bad request"
        case _:
            return "Something's wrong with the internet"
  • “变量名” _ 被作为 通配符 并必定会匹配成功

  • 定义函数

def fib(n):   
    """Print a Fibonacci series up to n."""
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

函数内的第一条语句是字符串时,该字符串就是文档字符串,也称为 docstring

默认值只计算一次。默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果。

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))
print(f(2))
print(f(3))
输出结果如下:

[1]
[1, 2]
[1, 2, 3]
不想在后续调用之间共享默认值时,应以如下方式编写函数:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

最后一个形参为 **name 形式时,接收一个字典
*name 形参接收一个元组

  • 特殊参数

函数定义中未使用 / 和 * 时,参数可以按位置或关键字传递给函数。

standard_arg(2)  //按位置传递参数

standard_arg(arg=2)  //按关键字传递参数

def pos_only_arg(arg, /):

def kwd_only_arg(*, arg):

def combined_example(pos_only, /, standard, *, kwd_only):
  • lambda表达式
def make_incrementor(n):
    return lambda x: x + n
  • 文档字符串

第一行应为对象用途的简短摘要。
文档字符串为多行时,第二行应为空白行,在视觉上将摘要与其余描述分开。

def my_function():
    """Do nothing, but document it.

    No, really, it doesn't do anything.
    """
    pass

print(my_function.__doc__)

五、数据结构


  • 列表

list.insert(len(a),x) = append(x)
list.remove(x)
list.pop()
list.sort()
list.reverse()

  • 用列表实现堆栈

pop() append()

  • 用列表实现队列

popleft() append()

  • 列表推导式
squares = []
for x in range(10):
    squares.append(x**2)


squares = [x**2 for x in range(10)]

l = [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
  • 嵌套的列表推导式
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
#外层循环是 for i in range(len(matrix[0])),它遍历了原始矩阵的每一列的索引。内层循环是 for row in matrix,它遍历了原始矩阵的每一行。
  • 集合

创建空集合只能用 set(),不能用 {},{} 创建的是空字典

a = set('abracadabra')
b = set('alacazam')
a-b  a+b  a&b  a^b
  • 字典

tel = {'jack': 4098, 'sape': 4139}
tel['guido'] = 4127
对字典执行 list(d) 操作,返回该字典中所有键的列表

在字典中循环时,用items()方法可同时取出键和对应的值:

knights = {'gallahad': 'the pure', 'robin': 'the brave'}
for k, v in knights.items():
    print(k, v)

在序列中循环时,用 enumerate()函数可以同时取出位置索引和对应的值:
for i, v in enumerate(['tic', 'tac', 'toe']):
print(i, v)

逆向循环序列时,先正向定位序列,然后调用 reversed() 函数:

for i in reversed(range(1, 10, 2)):
    print(i)

使用 set()去除序列中的重复元素

  • 比较运算符

in not in 用于执行确定一个值是否存在(或不存在)于某个容器中的成员检测
is is not 用于比较两个对象是否是同一个对象
and or

六、模块


Python 把各种定义存入一个文件,在脚本或解释器的交互式实例中使用。这个文件就是 模块 ;模块中的定义可以导入到其他模块或主模块。
其文件名是模块名加后缀名.py。在模块内部,通过全局变量 __name__可以获取模块名(即字符串)

  • 导入模块
import fibo
fibo.fib(1000)

from fibo import fib, fib2
fib(500)

from fibo import *
fib(500)

import fibo as fib
fib.fib(500)

from fibo import fib as fibonacci
fibonacci(500)
  • 以脚本方式执行模块

python fibo.py <arguments>

这项操作将执行模块里的代码,和导入模块一样,但会把 __name__ 赋值为 "__main__"。 也就是把下列代码添加到模块末尾:

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

这个文件既能被用作脚本,又能被用作一个可供导入的模块,因为解析命令行参数的那两行代码只有在模块作为“main”文件执行时才会运行

  • dir()函数

内置函数 dir()用于查找模块定义的名称。返回结果是经过排序的字符串列表

包是一种用“点式模块名”构造 Python 模块命名空间的方法
例如,模块名 A.B 表示包 A 中名为 B 的子模块
例如一个包的架构:

image.png

导入包时,Python 搜索 sys.path 里的目录,查找包的子目录。
必须要有 __init__.py文件才能让 Python 将包含该文件的目录当作包来处理。
这可以防止具有通用名称的目录如 string 在无意中屏蔽后续出现在模块搜索路径中的有效模块。
在最简单的情况下,init.py 可以只是一个空文件,但它也可以执行包的初始化代码或设置 all 变量。

import sound.effects.echo

from sound.effects import echo

from sound.effects.echo import echofilter
  • 从包中导入 *

如果包的 init.py 代码定义了列表 all,运行 from package import * 时,它就是被导入的模块名列表。

__all__ = ["echo", "surround", "reverse"]

如果没有定义 all,from sound.effects import * 语句 不会 把包 sound.effects 中所有子模块都导入到当前命名空间;该语句只确保导入包 sound.effects

  • 相对导入

可以用 import 语句的 from module import name 形式执行相对导入

下面的导入语句使用前导句点表示相对导入中的当前包和父包

from . import echo
from .. import formats
from ..filters import equalizer

注意,相对导入基于当前模块名。因为主模块名永远是 "main",所以如果计划将一个模块用作 Python 应用程序的主模块,那么该模块内的导入语句必须始终使用绝对导入。

包还支持一个特殊属性 __path__。在包的 __init__.py 中的代码被执行前,该属性被初始化为一个只含一项的列表,该项是一个字符串,是 init.py 所在目录的名称

七、输入与输出


输出格式

  • 格式化字符串字面值
f'Results of the {year} {event}'

# 将 pi 舍入到小数点后三位
print(f'The value of pi is approximately {math.pi:.3f}.')

print('We are the {} who say "{}!"'.format('knights', 'Ni'))

print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs

print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam

#使用关键字参数名引用值
print('This {food} is {adjective}.'.format(
      food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.

'{:-9} aaabbbb votes  {:2.2%}'.format(var1, var2)
  • 旧式字符串格式化方法
print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.

读写文件

  • open(filename, mode, encode)
    f = open('workfile', 'w', encoding="utf-8")
    mode的值包括 'r' ,表示文件只能读取;'w' 表示只能写入(现有同名文件会被覆盖);'a' 表示打开文件并追加内容,任何写入的数据会自动添加到文件末尾。'r+' 表示打开文件进行读写。mode 实参是可选的,省略时的默认值为 'r'
    mode后面加上一个 'b' ,可以用 binary mode 打开文件

  • with open

在处理文件对象时,最好使用 with 关键字。优点是,子句体结束后,文件会正确关闭,即便触发异常也可以。而且,使用 with 相比等效的 try-finally 代码块要简短得多:

with open('workfile', encoding="utf-8") as f:
    read_data = f.read()

# We can check that the file has been automatically closed.
f.closed
True

  • 文件对象的方法

f.read(size) 可用于读取文件内容并返回字符串(文本模式),或字节串对象(在二进制模式下)。
size 是可选的数值参数。省略 size 或 size 为负数时,读取并返回整个文件的内容

f.readline() 从文件中读取单行数据

for line in f:
    print(line, end='')

f.write(string) 把 string 的内容写入文件,并返回写入的字符数。

f.tell()返回整数,给出文件对象在文件中的当前位置

f.seek(offset, whence)可以改变文件对象的位置

  • 使用JSON

只需一行简单的代码即可查看某个对象的 JSON 字符串表现形式:

import json
x = [1, 'simple', 'list']
json.dumps(x)
'[1, "simple", "list"]'

dumps()函数还有一个变体dump(),将对象序列化为text file。因此,如果 f 是text file 对象,可以这样做:

json.dump(x, f)

# 解码对象
x = json.load(f)

八、异常


  • 异常的处理

try 语句的工作原理如下:

首先,执行 try 子句 (try 和 except 关键字之间的语句)。

如果没有触发异常,则跳过 except 子句,try 语句执行完毕。

如果在执行 try 子句时发生了异常,则跳过该子句中剩下的部分。 如果异常的类型与 except 关键字后指定的异常相匹配,则会执行 except 子句,然后跳到 try/except 代码块之后继续执行。

如果发生的异常与 except 子句 中指定的异常不匹配,则它会被传递到外部的 try 语句中;如果没有找到处理程序,则它是一个 未处理异常 且执行将终止并输出如上所示的消息。

try:
    this_fails()
except ZeroDivisionError as err:
    print('Handling run-time error:', err)
  • 触发异常

raise 语句支持强制触发指定的异常

唯一的参数就是要触发的异常。这个参数必须是异常实例或异常类

raise ValueError  # shorthand for 'raise ValueError()'

如果只想判断是否触发了异常,但并不打算处理该异常,则可以使用更简单的 raise 语句重新触发异常:

try:
    raise NameError('HiThere')
except NameError:
    print('An exception flew by!')
    raise
  • 异常链

如果一个未处理的异常发生在 except 部分内,它将会有被处理的异常附加到它上面,并包括在错误信息中

try:
    open("database.sqlite")
except OSError:
    raise RuntimeError("unable to handle error")

如果存在 finally 子句,则 finally 子句是 try 语句结束前执行的最后一项任务。不论 try 语句是否触发异常,都会执行 finally 子句

九、类


Python 的类有点类似于 C++ 和 Modula-3 中类的结合体

  • 作用域

global语句用于表明特定变量在全局作用域里,并应在全局作用域中重新绑定;
nonlocal语句表明特定变量在外层作用域中,并应在外层作用域中重新绑定。

  • 类定义:

在实践中,类定义内的语句通常都是函数定义
当(从结尾处)正常离开类定义时,将创建一个 类对象

三种对象类型

  • Class 对象

类对象支持两种操作:属性引用和实例化。

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

#属性引用
obj.name

# 类的 实例化
#实例化操作会创建一个空对象
x = MyClass()

# __init__()  创建带有特定初始状态的自定义实例 eg:
def __init__(self):
    self.data = []

# __init__() 方法还可以有额外参数,提供给类实例化运算符的参数将被传递给 __init__()
class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart

x = Complex(3.0, -4.5)
x.r, x.i
(3.0, -4.5)
  • 实例对象
    实例对象所能理解的唯一操作是属性引用。 有两种有效的属性名称:数据属性和方法。

  • 方法对象

调用 x.f() 其实就相当于 MyClass.f(x)

f定义为:
def f(self): return 'hello world'

  • 类和实例变量
class Dog:

    kind = 'canine'         # class variable shared by all instances

    def __init__(self, name):
        self.name = name    # instance variable unique to each instance

>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'

self.后面的变量相当于private
而直接定义在类里面的数据是共享的。

方法的第一个参数常常被命名为 self。 这也不过就是一个约定: self 这一名称在 Python 中绝对没有特殊含义。但是要注意,不遵循此约定会使得你的代码对其他 Python 程序员来说缺乏可读性,而且也可以想像一个 类浏览器 程序的编写可能会依赖于这样的约定。

方法可以通过使用 self 参数的方法属性调用其他方法:

class Bag:
    def __init__(self):
        self.data = []

    def add(self, x):
        self.data.append(x)

    def addtwice(self, x):
        self.add(x)
        self.add(x)

  • 继承

当基类定义在另一个模块中的时候
class DerivedClassName(modname.BaseClassName):
(对 C++ 程序员的提示:Python 中所有的方法实际上都是 virtual 方法。)

有一种方式可以简单地直接调用基类方法:
即调用 BaseClassName.methodname(self, arguments)
Python 也支持一种多重继承。

  • 私有变量

大多数 Python 代码都遵循这样一个约定:带有一个下划线的名称 (例如 _spam) 应该被当作是 API 的非公有部分 (无论它是函数、方法或是数据成员)。
由于存在对于类私有成员的有效使用场景(例如避免名称与子类所定义的名称相冲突),因此存在对此种机制的有限支持,称为 名称改写。 任何形式为 __spam 的标识符(至少带有两个前缀下划线,至多一个后缀下划线)的文本将被替换为 _classname__spam,其中 classname 为去除了前缀下划线的当前类名称。 这种改写不考虑标识符的句法位置,只要它出现在类定义内部就会进行。

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable) #在构造函数中调用了私有方法 __update

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)
# 将 update 方法赋值给私有方法 __update
    __update = update
  • 伪结构体
from dataclasses import dataclass

@dataclass
class Employee:
    name: str
    dept: str
    salary: int

john = Employee('john', 'computer lab', 1000)
john.dept
'computer lab'
john.salary
1000
  • 迭代器

iter()

s = 'abc'
it = iter(s)
it
<str_iterator object at 0x10c90e650>
next(it)
'a'
next(it)
'b'
next(it)
'c'
next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration
  • 生成器

生成器 是一个用于创建迭代器的

十、标准库简介


  • 操作系统接口
    一定要使用 import os 而不是 from os import * 。这将避免内建的 open() 函数被 os.open() 隐式替换掉
import os
os.getcwd()      # Return the current working directory
'C:\\Python311'
os.chdir('/server/accesslogs')   # Change current working directory
os.system('mkdir today')   # Run the command mkdir in the system shell

import shutil
shutil.copyfile('data.db', 'archive.db')
'archive.db'
shutil.move('/build/executables', 'installdir')
'installdir'
  • 字符串模式匹配
import re
re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'
  • 互联网访问

smtplib 用于发送邮件

import smtplib
server = smtplib.SMTP('localhost')
server.sendmail('soothsayer@example.org', 'jcaesar@example.org',
"""To: jcaesar@example.org
From: soothsayer@example.org

Beware the Ides of March.
""")
server.quit()
  • 性能测量
from timeit import Timer
Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791
  • 多线程
import threading, zipfile

class AsyncZip(threading.Thread):
    def __init__(self, infile, outfile):
        threading.Thread.__init__(self)
        self.infile = infile
        self.outfile = outfile

    def run(self):
        f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
        f.write(self.infile)
        f.close()
        print('Finished background zip of:', self.infile)

background = AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print('The main program continues to run in foreground.')

background.join()    # Wait for the background task to finish
print('Main program waited until background was done.')
  • 日志记录
import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')

十二、虚拟环境和包


相当于一个容器,nbcs

应用程序有时需要特定版本的库,可以创建一个 virtual environment,一个目录树,其中安装有特定Python版本,以及许多其他包。

用于创建和管理虚拟环境的模块称为 venv

#创建虚拟环境,确定放置的目录
python -m venv tutorial-env #创建 tutorial-env 目录

# 创建虚拟环境后,您可以激活它。
tutorial-env\Scripts\activate.bat #Windows上
source tutorial-env/bin/activate #Unix上

  • pip的使用

python -m pip uninstall
python -m pip show
python -m pip list
python -m pip freeze
requirements.txt
install -r

python -m pip install novas
python -m pip install requests==2.6.0
python -m pip install --upgrade requests
# 显示包的版本信息、位置等
python -m pip show requests
#显示已安装的所有包
python -m pip list

#输出已安装的包到指定文件,可供install -r命令使用
python -m pip freeze > requirements.txt

python -m pip install -r requirements.txt
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容