Python简介

简介

Python是一门跨平台、开源、免费的解释性高级动态编程语言,同时也支持伪编译,即将python源程序转换为字节码来优化程序和提高运行速度,通过py2.exepyinstaller工具还能将python程序转换为拓展名为exe的可执行程序,以在未安装python解释器和相关依赖包的Windows平台上运行。

解释性语言和诸如C和C++不同的是,程序不需要在运行前进行编译,而是在运行时进行编译,解释器负责在每个语句执行时解释程序代码,由于每执行一行代码都需要翻译一次,所以效率较编译型语言低一些。

另外,python作为动态编程语言,其中的变量并不是在计算机内存中被写入的某个值,而只是指向内存的标签或名称,所以动态编程语言的变量没有一个固定的类型。

python基础知识

利用pip管理拓展库

目前,pip已经成为管理python拓展库的主流方式,使用pip不仅可以实时查看本机已经安装的python拓展库列表,还支持python拓展库的安装,升级和卸载等操作。常用的pip命令使用方法如下表所示:

pip命令 说明
pip install Somepackge 安装SomePackge模块
pip list 列出当前已安装的所有模块
pip install -upgrade SomePackage 升级SomePackage模块
pip uninstall SomePackage 卸载SomePackage模块
pip install SomePackage.whl 使用whl文件直接安装SomePackage

对于大部分拓展库,利用pip工具都能直接在线安装,不过有时会因为缺少VC编辑器或依赖文件而失败,此时可从http://www.lfd.uci.edu/~gohlke/pythonlibs/下在扩展库编译好的whl文件,之后利用pip install SomePackage.whl命令进行离线安装即可。

通常直接使用pip install命令由于源不在国内的原因下载速度会很慢,所以可以通过-i命令指定国内的镜像站,下面列出几个常用的镜像站:

  • 清华:Simple Index

  • 中科大:Simple Index

当计算机中安装了多个版本的Python开发环境时,在某个版本下安装的扩展库无法在其他版本中使用,这个小细节通过观察Python的安装文件夹很容易发现,安装多个Python版本时,各个版本拥有自己的安装文件夹,而各自的扩展库安装位置即位于这些文件夹中。

对象模型

对象是Python语言中最基本的概念之一,Python中一切都是对象。内置对象例如数字、字符串、列表、元组、字典、集合、del命令以及各个内置函数可供开发者直接调用,一些拓展性对象则需要导入特定模块才能使用,例如math模块中的正弦函数sin()time模块中的返回当前时间函数time()等。

常用的Python内置类型有int, float, complex, str, bytes, list, dict, tuple, set, bool, NoneType, Exception等等,这些类型都将在之后的学习中陆续接触。

变量类型

Python中不需要事先声明变量名及其类型,直接给变量赋值即可创建各种类型的变量。虽然不需要在使用前显式地声明变量及其类型,但Python仍属于强类型编程语言,Python解释器会根据赋值或运算来自动推断变量类型。创建变量之后在显示修改其类型或删除之前,变量将持续保持之前的类型。

另外,前文已经提到过,Python作为一种动态类型语言,即变量仅仅是一个指向某一内存地址的标签。根据变量指向的内存中存放的值的类型不同,变量的类型是可以随时发生变化的。

当有多个变量指向同一内存地址中的数据时,每当修改其中一个变量的值,则该标识符将指向新值所在的内存地址,旧值并不改变(也就是说,Python中的赋值操作仅仅是将被赋值的变量指向了右值指向的对象,而不是直接对被赋值变量指向的对象进行修改)。

 x=1
 y=x
 print(id(x),id(y))#3064760854832 3064760854832,两个标识符x和y都指向同一对象1,对象的地址相同;
 x+=2
 print(id(x),id(y))#3064760854864 3064760854832,x自增2后,y仍指向1,而x指向新对象2;
 #对x的值进行修改时,首先读取x指向的值,并令其与2相加,将新结果存放在新的内存中,最后将x指向新内存空间;

需要注意的是,Python具有自动内存管理功能,会跟踪所有的值,当某个值不被任何变量指向时,将会自动将该值销毁以释放内存。所以,大多数情况下,Python开发者不需要考虑过多内存管理的问题(但是由于自动内存管理的操作可能并不会及时进行,所以某些情况下显示地删除指向是必要的)。

Python采用的是基于值的内存管理方式,如果为不同变量赋值为相同值,则该值在内存中仅保留一份,多个变量指向同一内存地址。当Python启动时,会自动对[-5,256]范围内的整数进行缓存,也就是说若多个变量的值相等且在[-5,256]范围内,则这些变量将使用相同的预先开辟的内存空间。

对于区间[-5,256]外的整数,相同程序或交互模式下相同语句中的同值不同名变量会共用相同的内存空间,而在不同程序或交互模式下的不同语句将不遵守该规则。

 a,b=1,1
 print(id(a)==id(b))#True
 a,b=-6,-6
 print(id(a)==id(b))#True,由于处于相同程序中,对于整数只要值相同则变量指向的地址相同,无论是否处于[0,256]中;

Python不会对实数进行缓存,其内存管理方式类似于[-5,256]范围之外的整数,相同程序或交互模式下相同语句中的同值不同名变量会共用相同的内存空间,而在不同程序或交互模式下的不同语句将不遵守该规则。

 a,b=3.14,3.14
 print(id(a)==id(b))#True

数值类型

数字在Python中属于不可变对象,即修改整形变量值的时候并不是真的修改变量的值,而是先把值存放到内存中然后修改变量使其指向新的内存地址。该特性在上述实例中已经有所体现,不仅是整数,浮点数、复数等数字类型以及其他类型的变量也具有相同的特点。

Python的数值类型主要有整数、浮点数和复数,整数类型可分为十进制整数(例如1,-2),十六进制整数(例如0x10,0xfa),八进制整数(例如0o35,0o11)和二进制整数(例如0b100,0b110)。

Python 3.6.x或以上的版本支持在数字的中间位置使用单个下划线作为分隔来提高数字的可读性,所以在程序中写入数字常量时可采用该书写格式,下划线出现的位置遵循的规则与千位分隔符相同,可以位于数字中间的任意位置。

Python中的数字可以表示任意大的数值,不受变量类型的限制,因此可以利用Python进行复杂的数学运算。

 x=4+4j
 y=2+3j
 print(x+y)#(6+7j)
 x=74198375984375982734584973285743958
 print(x**2)#5505398998718822584864598019121158120147533490850676426335877533505764

字符类型

Python中,字符串属于不可变序列,一般使用单引号、双引号或三引号(分单和双)进行结点,三种方法通常根据需要可以相互嵌套以表示比较复杂的字符串。

三种表示方法中,特别地,一对三单引号或三双引号表示的字符串支持换行,支持排版格式较为复杂的字符串,常用于在程序中表示较长的注释(文档字符串)。

 print('HelloWorld!!!',"HelloWorld!!!")#HelloWorld!!! HelloWorld!!!
 print('''Hello
 World!!!''')
 #Hello
 #World!!!

Python支持转义字符,常用的转义字符如下表所示:

转义字符 描述
\(在行尾时) 续行符
\\ 反斜杠符号
\' 单引号
\" 双引号
\a 响铃
\b 退格(Backspace)
\e 转义
\000
\n 换行
\v 纵向制表符
\t 横向制表符
\r 回车
\f 换页
\oyy 八进制数,y 代表 0~7 的字符,例如:\o12 代表换行。
\xyy 十六进制数,以 \x 开头,yy代表的字符,例如:\x0a代表换行
\other 其它的字符以普通格式输出

转义字符的存在使得一些特殊符号例如'\',换行等能够通过字符串进行输出,但是与此同时也带来了歧义的问题。试图将字符串按原样输出时,可以在字符串界定符前加上字母'r''R'表示原始字符串,原始字符串中的特殊字符不进行转义,按原样输出。

原始字符串常用于正则表达式,也可以用来简化文件路径或网址的输入。需要注意的是,原始字符串不能以'\'结束,因为Python解释器会将作为界定符的'"转义(即使在原始字符串中也不可行)。

运算符

和其他语言一样,Python支持大多数算术运算符,关系运算符,逻辑运算符以及位运算符,并且遵循着与大多数语言一样的运算符优先级。在上述运算符的基础上,Python还增加了一些特有的运算符,例如成员测试运算符、同一性测试运算符等。

下面列出按优先级(从上至下优先级依此降低)排序的运算符表:

运算符 描述
** 指数 (最高优先级)
~ + - 按位翻转, 一元加号和减号 (后两个对应的方法名为+@和-@)
* / % // 乘,除,取模和取整除
+ - 加法减法
>> << 右移,左移运算符
& 按位与运算符
^ \| 位运算符
<= < > >= 比较运算符
<> == != 等于运算符
= %= /= //= -= += *= **= 赋值运算符
is is not 身份运算符
in not in 成员运算符
not and or 逻辑运算符

需要注意的是,Python中的除法有两种,///分别表示除法和整除运算(后者和C/C++中的整数除法类似,由于Python没有浮点数和定点数的区分,所以需要对两种运算做出分别)。

 print(1/2,1//2)#0.5 0

和很多语言不同的是,Python中的比较运算符是可以连续使用的。

 print(1<2<3)#True
 print(2>=2<=1)#False

和大多数语言的逻辑运算符一样,Python中的逻辑运算符也拥有惰性求值即仅计算必须计算的表达式的值的特性。设计条件表达式时如果能利用这个特性,将能大大提高程序运行的效率,减少不必要的计算和判断。

 print(1<2 or exec("print('Hello')"))#True,Hello并没有被输出,说明or之后的表达式并未被执行;

为了避免一些语言中频繁出现的===的错误,Python的条件表达式中不允许出现=,即不能利用赋值运算符的连续赋值特性将赋值运算集成到条件表达式中以精简代码。

if x=2:					#SyntaxError: invalid syntax
    print('Hello')

内置函数

内置函数指不需要导入任何模块即可直接使用的函数,利用dir(__builtins__)命令可以列出所有内置函数和内置对象,常用的内置函数有all()any()chr()等。

编写程序时应优先考虑使用内置函数,因为内置函数经过了多个版本的迭代已经十分成熟、稳定,并且速度相对较快。

对象的删除

Python中可以使用del命令来显式删除对象并解除其与值之间的指向关系。删除对象时,如果其指向的值还有别的变量指向,则不删除该值,否则删除该值。

del并不和C/C++中的delete一样删除对象,而是删除某个指向对象的名称,如果某个对象的所有名称都被删除了,Python将自动把该对象删除(事实上,在Python中是无法手动删除某个值的)。

seq_1=["hello","world"]
seq_2=seq_1
del seq_1
print(seq_2)#['hello', 'world'];

模块的导入与使用

在Python启动时,仅加载很少一部分基本模块,在需要时由开发者显式地加载其他模块,这种仅加载真正需要的模块和功能的设计大大减小了程序的运行压力和打包后可执行文件的大小。

导入模块时,Python首先在当前目录中查找需要导入的模块,如果没有找到则从sys.path所指定的目录中查找(所以对于自己写的模块,将其路径添加到path变量中即可导入模块中的内容),若仍未找到目标模块则提示模块不存在。

import sys
print(sys.path)    
#sys.path为一个列表,其中存放了模块的查找目录,可以看到当前目录为列表的第一个元素,所以优先在当前目录中查找;
'''['c:\\Users\\VeritySeeker\\OneDrive\\Code\\SingleSrcFile\\PythonSrcCode\\code', 'D:\\Python\\python39.zip', 'D:\\Python\\DLLs', 'D:\\Python\\lib', 'D:\\Python', 'C:\\Users\\VeritySeeker\\AppData\\Roaming\\Python\\Python39\\site-packages', 'D:\\Python\\lib\\site-packages']'''

导入模块会优先导入相应的.pyc文件(由.py文件编译得到的二进制文件),若相应的.pyc文件和.py文件不同步或者.pyc文件不存在则导入.py文件并将该模块文件编译为.pyc文件。

对于导入的模块,如果其中包含变量(而不仅只有类和函数)并且在调用过程中进行了大量修改,此时若希望重置这些变量以使模块执行正常的功能,可以使用impimportlib模块中的reload()函数重新加载模块。

from imp import reload			#从imp模块中导入reload函数;
reload(jieba)					#重新加载jieba库(仅作示例,事实上jieba库一般不需要进行重新加载的操作);

import [as ]

使用该格式导入模块后,需要在要使用的对象之前加上前缀,即以module.object的方式访问。也可以为导入的模块设置一个别名,然后使用nickname.object的方式使用其中的对象。

import jieba        	#导入jieba库
import jieba as fenci   #以fenci为别名导入jieba库

from import [as ]

使用该格式仅导入明确指定的对象,并为导入的对象起一个别名。这种方式可以减少查询次数,提高访问速度,同时减少程序员需要输入的代码量(不需要在调用时加上模块名前缀)。

还可以通过from modulename import *一次性导入模块中的所有对象(事实上并不是所有对象,而是在模块中通过__all__属性指定的对象),但一般情况下不推荐使用此方式以防止污染命名空间。

from jieba.analyse import extract_tags      
#从jieba.analyse文件中导入关键词提取函数;
from jiaba.analyse import extract_tags as KeyWords      
#从jieba.analyse库中以keyword为别名导入关键词提取函数

基本输入输出

在Python中,使用内置函数input()接收用户的键盘输入,用print()向屏幕输出。

x=input("Input:")
y=input("Input:")
r=float(x+y)						#由于x和y都为字符串,所以x+y应为'23.14',转化为浮点数后得到23.14;
s=int(x)+float(y)					#分别将x和y转化为目标类型的数据在进行运算,才能得到正确的结果;
print(x,y,r,s,sep=' ',end='\n')		#sep为分隔符,end为结束符;
'''
Input:2
Input:3.14
2 3.14 23.14 5.140000000000001
'''

无论用户输入什么,input()函数的返回值都是字符串,需要将其转为对应的类型才能进行数据的处理。

Python代码编写规范

和大多数其他编程语言通过花括号来组织代码块不同,Python程序是依靠代码块的缩进来体现代码之间的关系的。以选择结构为例,判断语句末尾的冒号和下一行的缩进表示一个代码块的开始,缩进结束则表示一个代码块的结束。

在大多数开发环境中,利用Ctrl+[Ctrl+]快捷键能方便的将当前行反缩进和缩进。

Python中常用的注释方式主要有两种,单行注释和多行注释。

  • 单行注释:以符号#开始,表示本行#之后的内容为注释;

  • 多行注释:包含在一对三引号(''')或三双引号(""")之间且不属于任何语句的内容将被解释器视作注释;

多行注释本质上就是一个独立的字符串,由于用三(双)引号表示的字符串支持换行,所以常用于多行注释中,实际上利用单引号或双引号都是合法的。

若一行语句太长,可以在行尾使用\来表示下面紧接的一行仍属于当前语句,也可以使用括号来包含多行内容。

print("HelloWorld",
    sep=' ',end='\n'
)#HelloWorld,利用括号将多行的各个参数包含,正常输出;
if 1<\
    2:print("HelloWorld")		#HelloWorld,在行尾利用\符号表示当前语句未结束,正常输出;

每个Python脚本在运行时都有一个__name__属性,如果脚本作为模块被导入,则__name__属性的值被自动设置为模块名。如果脚本独立运行,则其__name__属性值被自动设置为'__main__'

当自己编写模块时,在模块的结尾加上测试语句并将其用带__name__=='__main__'条件的if语句包含是个好习惯,此时如果将模块作为代码运行会自动执行测试代码,如果作为模块导入则不执行这部分内容。

import jieba
print(jieba.__name__,__name__,sep=' ')#jieba __main__

Python的文件名

在Python中,不同拓展名的文件类型有不同的含义和用途,常见的拓展名主要有以下几种:

  • py——Python源文件,有Python解释器负责解释执行;

  • pyw——Python源文件,常见于图形界面程序文件;

  • pyc——Python字节码文件,可用于隐藏Python源代码和提高运行速度;

  • pyd——一般是由其他语言编写并编译的二进制文件,常用于实现某些软件工具的Python编程接口插件或Python动态链接库。

当Python源代码作为模块使用时,第一次被导入时将被编译成字节码的形式,并在以后再次导入时优先使用.pyc文件以提高模块的加载和运行速度。直接执行Python程序文件时并不生成.pyc文件,但可以使用py_compile模块的compile()函数进行编译以提高加载和运行速度。

另外,Python还提供了compileall模块,其中包含complie_dir()compile_file()compile_path等方法,用以支持批量Python源程序文件的编译。

Python包的组织方式

包是Python用来组织程序文件和命名空间的重要方式,可以看作是包含大量Python程序模块的文件夹。在包的每个目录中都必须包含一个__init__.py文件,该文件可以是一个空文件,仅用于表示该文件夹是一个包。

__init__.py文件的主要作用是设置__all__变量以及执行初始化包所需的代码,其中__all__变量中定义的对象可以在使用from module import *时全部被正确导入。

假设有如下结构的包:

sound/
	__init__.py
	formats/
		__init__.py
		wavread.py
		wavwrite.py
	effects/
		__init__.py
		echo.py
		surround.py
	filters/
		__init__.py
		vocoder.py

在程序中可使用import sound.effects.eho导入包中的echo模块,然后使用完整的名字来访问或调用模块中的成员,例如sound.effects.echo.echofilter(input,output,delay=0.7,atten=4)

对于分级层次比较多的包,通常需要在导入时另起一个别名以简化代码编写。

你可能感兴趣的:(Python程序设计,python,开发语言)