python 的基本

python

解释器

调用解释器

  1. py/python (输入文件结束字符退出/quit())
  2. python -c command [arg] …
  3. python -m module [atg] … (交互模式加上 -i 参数)

具体查看 命令行

传入参数

命令行参数会被 sys模块 中的argv变量读取,在程序中import sys即可访问argv变量.此外argv[]这个列表最少也会有一个元素,没有参数则是空字符串.

解释器环境

默认采用utf-8字符编码,世界大多数语言的字符都可以作为变量,函数名,字符串字面值

若不使用默认编码,则需要在第一行添加特殊注释

1
# -*- coding: encoding -*-

在Unix中,也需添加特殊注释

1
#!/usr/bin/env python3

流程控制工具

  • if语句 else if 在python写作elif
  • for语句 不止对数值进行迭代,而是对任意序列进行迭代.range函数返回的是一个可迭代对象,并不是数值列表
  • 定义函数 函数体的第一个语句可以(可选的)是字符串文字,函数的 执行 会引入一个用于函数局部变量的新符号表,变量引用顺序:局部符号表->外层函数的局部符号表->全局符号表->内置名称符号表.全局变量和外层函数的变量不能在函数内部直接赋值.python函数如果没有returen 会返回内置名称None.形如 kwarg=value 的 关键字参数 来调用函数

循环的技巧

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

1
2
3
4
5
6
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
... print(k, v)
...
gallahad the pure
robin the brave

当在序列中循环时,用 enumerate() 函数可以将索引位置和其对应的值同时取出 enumerate(iterable[, start=0])

1
2
3
4
5
6
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe

enumerate返回一个枚举对象。iterable 必须是一个持迭代的对象.enumerate()返回的迭代器的 __next__()方法返回一个元组,里面包含一个计数值(从 start 开始,默认为 0)和通过迭代 iterable 获得的值。

等价于:

1
2
3
4
5
def enumerate(sequence, start=0):
n = start
for elem in sequence:
yield n, elem
n += 1

当同时在两个或更多序列中循环时,可以用 zip() 函数将其内元素一一匹配。

1
2
3
4
5
6
7
8
>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
... print('What is your {0}? It is {1}.'.format(q, a))
...
What is your name? It is lancelot.
What is your quest? It is the holy grail.
What is your favorite color? It is blue.

lambda表达式

它是一个匿名函数表达式,其用法为

lambda [arg1 [,arg2,.....argn]]:expression

解包参数列表

* 运算符编写函数调用以从列表或元组中解包参数;字典可以使用 ** 运算符来提供关键字参数

序列数据结构

python具有6种序列数据结构,常用的是列表和元组

列表

方法

这些方法只修改列表,没有打印出返回值,且返回值为None

  • list()list(iterable)进行构造
  • list.append(x) 在末尾添加一个元素.相当于a[len(a):] = [x]
  • list.extend(lterable) 使用可迭代对象的所有元素来拓展列表.相当于a[len(a):] = iterable
  • list.insert(i,x) 在给定的位置插入一个元素.第一个参数是要插入的元素的索引
  • list.remove(x) 移除列表中第一个值为 x 的元素.如果没有这样的元素,则抛出 valueError 异常
  • list.pop([i]) 删除列表中给定位置的元素并返回它.没有参数则删除最后一个元素并返回它
  • list.clear() 移除列表中的所有元素.等价于del a[:]
  • list.index(x[, start[, end]]) 返回列表中第一个值为 x 的元素的从零开始的索引.没有这样的元素将会抛出 ValueError 异常
  • list.count(x) 返回元素 x 在列表中出现的次数
  • list.sort(key=None, reverse=False) 对列表中的元素进行排序
  • list.reverse() 翻转列表中的元素
  • list.copy() 返回列表的一个浅拷贝. 等价于 a[:]

列表作为栈

因为存在append与pop方法则作为堆栈非常容易

1
2
3
stack = [3,4,5]
stack.append(6)
stack.pop()

列表作为队列

虽然通过内置方法可以实现队列的操作但是其效率非常的低下.所以如果要实现一个队列,可以引入collections 模块中 deque 对象(double-end-queue)

class collections.deque([iterable[, maxlen]])

deque对象返回一个双向队列对象,从左到右初始化,从iterable数据创建(可选).Deque 支持线程安全,内存高效添加(append)和弹出(pop),从两端都可以,两个方向的大概开销都是 O(1) 复杂度,下面是deuqe常用的方法

  • append(x) 添加 x 到右端
  • appendleft(x) 添加 x 到左端
  • pop() 移去并且返回一个元素,deque最右侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。
  • popleft()移去并且返回一个元素,deque最左侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。

元组

元组是由几个被逗号隔开的值组成.元组是immutable的,所以给元组中的一个单独的元素赋值是不允许的.

此外创建空元组使用的空括号即可emptytuple = (),创建一个元素的元组在后面加上一个 逗号 即可singleton = 'hello',

python中有序列 解包 和 打包 的概念.t = 12345, 54321, 'hello!' 是 元组打包 的一个例子,x, y, z = t是一个序列解包的列子,解包操作等号右边可以是任何数据类型,但是此操作要求序列元素数 与 左侧变量个数相等

集合

集合是由不重复元素组成的无序的集.集合对象支持集合的数学运算

可以使用花括号和set()创建集合,但是创建空集合只能使用set(),因为{}是创建一个空字典

1
2
3
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket) # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}

字典

以连续整数为索引的序列不同,字典是以 关键字 为索引的,关键字可以是任意不可变类型,通常是字符串或数字.如果一个元组只包含字符串、数字或元组,那么这个元组也可以用作关键字。但如果元组直接或间接地包含了可变对象,那么它就不能用作关键字.若重复定义键值对,则最后一个重复的键才有效.

可以用 del 来删除一个键值对。如果你使用了一个已经存在的关键字来存储值,那么之前与这个关键字关联的值就会被遗忘。用一个不存在的键来取值则会报错(keyError)。对一个字典执行 list(d) 将返回包含该字典中所有键的列表,dict()构造函数可以直接从键值对序列里创建字典

模块

是一个 Python 文件,以 .py 结尾.

模块可以包含直接的可执行语句,这些语句常用于初始化模块,在第一次import语句中会被执行,如果被当作脚本运行的话也是会被执行的

当模块是以脚本的方式启动的,则__name__被赋值为__main__,这样编写则可以当作脚本又可以当作可调入的模块

1
2
3
4
5
6
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))

$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34

每个模块都有属于自己的私有符号表,所以当import导入语句后,当前符号表并没有进入模块内,仍保存在模块名中.被导入的模块名存放在调入模块的全局符号表中。ps:通过dir()返回模块定义的名称,如果没有参数,则返回当前符号表中的定义过的名称.dir()不会列出内置函数和变量的名称。如果你想要这些,它们的定义是在标准模块 builtins

1
2
3
4
5
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__displayhook__',...

import导入语句后,使用模块名访问函数 modules.func.如果此函数使用频繁,则可以使用局部变量代替 vara = modules.func .如果带有 as,则可以更换导入模块的名字.此外import语句的变体 from modules import namea[,nameb[,...namec]]只会将名字导入到当前模块的符号表中,被导入的模块名不会被定义.或者可以直接导入所有名字 from modules import * 这会调入所有非以下划线_开头的名称.

如果在解释器会话中更改了模块,则因效率的考虑需要重启解释器import importlib; importlib.reload(modulename)

模块搜索路径

当一个模块被导入时,解释器会先寻找该名称的 内置模块 ,如果没有找到,则从sys.path变量给出的目录列表中寻找,在此变量中具有如下目录地址

  • 文件当前目录
  • PYTHONPATH
  • 安装的默认位置

sys.path是一个字符串列表,可以通过列表方法进行添加路径sys.path.append('/ufs/guido/lib/python')

编译后的模块

为了加速模块载入,Python在 __pycache__ 目录里缓存了每个模块的编译后版本,名称为 module.*version*.pyc

Python在两种情况下不会检查缓存。首先,对于从命令行直接载入的模块,它从来都是重新编译并且不存储编译结果;其次,如果没有源模块,它不会检查缓存

一个从 .pyc 文件读出的程序并不会比它从 .py 读出时运行的更快,.pyc 文件唯一快的地方在于载入速度

包是一个分层次的文件目录结构,但该文件夹下必须存在 __init__.py文件,用来执行包的初始化代码或设置 __all__ 变量

包导入推荐使用如下形式 from package import specific_submodule

此外当包被构造成子包时,可以使用绝对导入和相对导入其他子包

输入输出

键盘输入

  • raw_input([prompt]) 函数从标准输入读取一个行,并去掉结尾的换行符
  • input([prompt]) 函数和可以接收一个Python表达式作为输入,并将运算结果返回

格式化字符串

  1. 在字符串的开始引号或三引号之前加上一个 fF,则可以在{ }之间引用变量或字面值的python表达式
  2. 字符串的format()方法

文件

open()返回一个 file object,最常用的有两个参数: open(filename, mode)

推荐写法:

1
2
3
>>> with open('workfile') as f:
... read_data = f.read()
>>> f.closed
文件对象方法
  • file.read(size) 读取一些数据并将其作为字符串,字节串对象返回.size 是可选的. 当 size 被省略或者为负数时,将读取并返回整个文件的内容;如果文件的大小是内存的两倍会出现问题. 如果已到达文件末尾将返回一个空字符串 ''
  • f.readline() 从文件中读取一行,换行符保留在在字符串末尾,若已到达文件末尾,则返回空字符串'',如果要按行读取,则推荐循环遍历文件对象 for line in f: ,如果想以列表的方式读取,可以直接 list(f) f.readlines()
  • f.write(string) 会把 string 的内容写入到文件中,并返回写入的字符数
  • f.tell() 返回一个整数,给出文件对象在文件中的当前位置,表示为二进制模式下时从文件开始的字节数

json

  • json.dumps 用于将 Python 对象编码成 JSON 字符串.格式化输出json.dumps({'a': 'Runoob', 'b': 7}, sort_keys=True, indent=4, separators=(',', ': '))

    dumps的变体dump将序列对象替换为了text file 对象 json.dump(x,f)

  • json.loads 用于解码 JSON 数据。该函数返回 Python 字段的数据类型

错误与异常

try...except语句推荐使用else子句,表示没有异常执行的句子

raise语句允许程序员强制发生指定的异常,参数是异常实例

namespace (命名空间)是一个从名字到对象的映射,

类中包含__doc__属性,返回文档字符串

继承

1
2
3
4
class DerivedClassName(BaseClassName):
<statement-1>
...
<statement-N>

Python有两个内置函数可被用于继承机制:

  • isinstance() 来检查一个实例的类型: isinstance(obj, int)obj.__class__为 int 或某个派生自 int 的类时为 True.
  • issubclass() 来检查类的继承关系: issubclass(bool, int)为 True.

迭代器

for 语句会在容器对象上调用 iter()。 该函数返回一个定义了 __next__()方法的迭代器对象,此方法将逐一访问容器中的元素。 当元素用尽时,__next__() 将引发 StopIteration 异常来通知终止 for 循环。 你可以使用 next() 内置函数来调用 __next__() 方法

生成器

Generator 是一个用于创建迭代器的简单而强大的工具

返回数据时会使用 yield 语句。 每次对生成器调用 next() 时,它会从上次离开位置恢复执行.例子

1
2
3
4
5
6
7
8
9
>>>def reverse(data):
... for index in range(len(data)-1, -1, -1):
... yield data[index]
>>> for char in reverse('golf'):
... print(char)
f
l
o
g

附录

时间

获得时间戳

1
2
import time
ticks = time.time()

获得时间元组,要将浮点数传递给如localtime之类的函数

1
2
3
import time
localtime = time.localtime(time.time())
print(localtime.tm_year...)

RE


评论




Blog content follows the Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License

loading...loading... , total visits times