Python Tutorial
打开Python解释器的三种方法:
1、python
在命令行打开解释器
2、python -c python_statements [arg] ...
解释器直接执行python语句,由于语句可能含有空格,语句可以用引号包括起来
3、python -m module [arg] ...
解释器执行python源文件模块
Python命令参数传递
参数保存在sys模块的argv列表变量中。
举例:python -i -c "print('hello')"
结果:sys.argv为['-c']
再举例:python -i -m pip --version
结果:sys.argv为['...\\pip\\__main__.py', '--version']
Python源代码编码
默认情况下,Python源代码采用UTF-8编码。
更改编码方式,可以在源代码首行进行声明,语法为:
# -*- coding: encoding -*-
举例:# -*- coding: cp1252 -*-
唯一特例情况更改编码方式应该放在第二行,这种情况下第一行为"shebang" line
#!/usr/bin/env python
# -*- coding: cp1252 -*-
"shebang" line
Unix系统中,在Python源代码第一行添加"shebang" line的作用是Python的源代码脚本可以直接执行
#!/usr/bin/env python
Windows系统中不需要"shebang" line也可以直接执行后缀为.py的源代码
除法运算 /和//
在算术运算过程中,/(除法)总是返回浮点数。
整数之间除法要获得整数,应当使用//(floor division)
举例:3/2为1.5,3//2为1,-3//2为-2
乘法运算 *, 幂运算 **
举例:2*3为6,2**3为8
交互模式下的_
交互模式下的_是一个变量,保存最后一个打印的表达式
举例:2*3
交互模式下会打印出6
输入_
交互模式下会再次打印出6
如果你在交互模式下给变量_进行赋值,会创建一个独立的局部变量_而掩盖了built-in的变量_。
raw string
在第一个引号之前加一个r
举例:print(r'C:\some\name') # note the r before the quote
结果显示为:C:\some\name
true和false
true:非0整数,任何长度为非0的序列
false:整数0,任何长度为0的序列
else可用于循环
循环语句可能有else子句,当for循环由于iterable耗尽而终止时,或者当while循环条件变为false时,它会被执行,但当循环被break语句终止时,它不会被执行。
__doc__属性
模块、类、函数等的__doc__属性:即模块、类、函数等的首部"""...docstring..."""内容。
__annotations__属性
函数的__annotations__属性:即函数注释。
函数注释作为字典存储在函数的__annotations__属性中,对函数的任何其他部分都没有影响。
参数注释由参数名称后的冒号定义,后面跟着一个计算为注释值的表达式。
返回注释由一个文字->和一个表达式定义,位于参数列表和表示def语句结尾的冒号之间。
举例:
函数注释:__annotations__属性__name__属性
模块文件的名称(不含.py)。
函数
函数中的所有变量赋值都将值存储在局部符号表中;而变量引用首先查找局部符号表,然后查找封闭函数的局部符号表、全局符号表,最后查找内置名称表。因此,全局变量和封闭函数的变量不能在函数内直接赋值(除非对于全局变量,在全局语句中命名,或者对于包围函数的变量,在非局部语句中命名),尽管它们可以被引用。
函数调用的实际参数(自变量)在被调用函数的本地符号表中引入;因此,使用按值调用传递参数(其中值始终是对象引用,而不是对象的值)。当一个函数调用另一个函数时,会为该调用创建一个新的本地符号表。
函数定义将函数名称与当前符号表中的函数对象相关联。解释器将该名称指向的对象识别为用户定义的函数。其他名称也可以指向同一函数对象,也可以用于访问该函数。
事实上,即使没有return语句的函数也会返回一个值,尽管这是一个相当无聊的值。该值称为None(它是一个内置名称)。
默认值是在定义范围中的函数定义点进行计算的。举例:
i=5
def f(arg=i):
print(arg)
i=6
f()
结果显示为5。
默认值只计算一次。当默认对象是可变对象(如列表、字典或大多数类的实例)时,这会有所不同。举例:
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
函数参数中还可能用到/和*,具体请查阅官方文档。
Lists
列表可以作为栈(使用append()和pop()方法可以高效实现后进先出),列表也可以作为队列(先进先出),但效率不高。为了实现高效队列,可以使用collections.deque。
Sets
创建一个空的集合必须使用set(),不能用{}({}创建的是一个空字典)。
Dictionaries
字典的key可以是任何的immutable类型,包括不含可修改元素的元组。
import module会如何搜索路径
当一个模块被导入时,解释器首先在built-in模块(sys.builtin_module_names)中搜索这个名字。如果没有发现,进而在系统路径(sys.path)中搜索。
"Compiled" Python文件
为了加速模块加载,Python会缓存“编译”好的模块文件(文件名样式为module.version.pyc)到__pycache__目录。
在Python命令行中,可以使用-O(剔除代码中的assert语句执行)或者-OO(剔除代码中的assert语句和__doc__字符串)可以减少模块编译后的文件大小。
程序从.pyc读取运行并不比从.py读取运行速度快,只是加载速度快。
模块compileall可以为一个目录下的所有模块创建.pyc文件。
标准模块sys
变量sys.ps1和sys.ps2定义了交互界面的主提示符">>>"和次提示符"...",这两个变量只在交互模式的解释器中定义。
sys.path为解释器对模块的搜索路径,该值初始默认值来源于系统环境变量PYTHONPATH,若不存在系统环境变量PYTHONPATH,则从built-in默认获取。
内建dir()函数
显示当前或对应参数定义的所有名称(变量名,模块名,函数名等等)。
Packages
包是通过使用“.模块名称”来构建Python模块名称空间的一种方式,简单来说,包是模块的集合。
包的结构示例导入包时,Python会在系统路径(sys.path)中搜索包。
__init__.py文件作用是使得Python把包含文件的文件夹当作包来处理。这样可以防止具有通用名称(如string)的目录无意中隐藏模块搜索路径上稍后出现的有效模块。
import语句使用以下约定:如果包的__init__.py代码定义了一个名为__all__的列表,则它将被视为遇到从包导入*时应该导入的模块名称列表。如果未定义__all__,则sound.effects import*中的语句不会将包sound.efects中的所有子模块导入当前命名空间;它只确保包sound.effects已经导入。
包支持另一个特殊属性__path__。
Formatted String Literals (also called f-strings for short)
字符串前面加上f或F,并将表达式写成{expression}。举例:
f字符串示例1在“:”之后传递一个整数将导致该字段的宽度为最小字符数。这对于使列对齐非常有用。
f字符串示例2在格式化值之前,可以使用其他修饰符对其进行转换。'!a'应用ascii(),'!s'应用str(),并且'!r'应用repr()。
JSON
通过json.dumps(a_object)可以看出json字符串是如何表示该对象的。
json.dump(a,f)可以把对象a写入文件f。
a=json.load(f)可以从f文件读取。
命名空间Namespaces
命名空间是从名称到对象的映射。
关于名称空间,需要了解的重要一点是,不同命名空间中的名称之间绝对没有关系;例如,两个不同的模块都可以定义一个函数maximum而不会混淆——模块的用户必须在其前面加上模块名称。
解释器的顶级调用执行的语句,无论是从脚本文件中读取还是以交互方式执行,都被认为是名为__main__的模块的一部分,因此它们有自己的全局命名空间。
函数的本地命名空间在调用函数时创建,在函数返回或引发未在函数内处理的异常时删除。当然,递归调用每个都有自己的本地命名空间。
作用域 Scopes
作用域是Python程序的一个文本区域,在作用域中可以直接访问命名空间。这里的“可直接访问”意味着对名称的非限定引用试图在命名空间中查找该名称。
虽然作用域是静态确定的,但它们是动态使用的。在执行过程中的任何时候,都有3或4个嵌套作用域的命名空间可以直接访问:
•首先搜索最内层作用域,最内层作用域包含本地名称。
•从最近的包含函数的作用域开始依次往外搜索,包含非局部、非全局名称。
•倒数第二个作用域,包含当前模块的全局名称。
•最外层的作用域(最后搜索),包含内置名称的命名空间。
要重新绑定在最内部范围之外找到的变量,可以使用非局部语句;如果没有声明为非局部的,那么这些变量是只读的(尝试写入这样的变量只会在最内部的范围中创建一个新的局部变量,而保持同名的外部变量不变)。
命名空间和作用域举例