python详解(1)--准备工作与一些基础理论

本文介绍了Python编程语言的基本概念,包括其面向对象特性、解释型与编译型的区别、强类型与弱类型的特点。此外,还深入讲解了计算机中的原码、反码与补码,以及字符编码与字节的关系。最后,讨论了Python的优缺点、学习准备和编码规范。内容适合初学者了解Python编程的基础知识。
摘要由CSDN通过智能技术生成

此系列文记录了本人在学习python时的顺序以及了解的所有相关内容,因此可能偶尔出现好像与系列主题关系不大的部分,理论深度也没有按照由低到高进行排列,但都有内部联系,因为是作个人知识归档整理用,所以可能根据个人习惯内容比较晦涩,如有问题,请向我提出,谢谢!

一、计算机编程语言的特性

编程语言:是用来定义计算机程序的形式语言。它是一种被标准化的交流技巧,用来向计算机发出指令。一种计算机语言让程序员能够准确地定义计算机所需要使用的数据,并精确地定义在不同情况下所应当采取的行动。

面向对象语言:以对象为基本程序结构单位的程序设计语言,其以功能来划分问题,将所有的问题都归结为对象的属性,采用基于对象的概念建立模型。
①特性:抽象、封装、继承、多态;
②优缺点:易维护、易复用、易扩展,性能低;
③面向对象的开放封闭原则:即已经实现的功能代码不允许被修改,但可以被扩展。

面向过程语言:以过程为中心的编程语言,是一种基础的顺序的思维方式。
①特性:性能高、流程化;
②优缺点:维护、复用、扩展难度高,性能高;
:面向对象语言也可以进行面向过程式的编程,两者的区分度其实并不高,重点在于实现功能的思想。

解释型语言:在运行的时候逐行将程序翻译为机器语言,再次运行时需要重新翻译,需要解释器;其速度慢,对系统要求高,大量消耗系统资源,解释器简单,bug易找,平台独立性,安全性较好。

编译型语言:将写好的代码编译为一个完整的结果文件(如.EXE),再次运行时不需要重新编译,需要编译器;其速度快,对系统要求低,编译器复杂(编译时间长),代码复杂,bug难找,跨平台性和安全性较差。
:计算机只能识别机器语言(一组有意义的二进制代码),因此需要通过一定的方式,将高级语言翻译成机器语言,解释型语言即使用解释器,编译型语言使用编译器。

静态类型语言:指在编译时变量的数据类型即可确定的语言,多数静态类型语言要求在使用变量之前必须声明数据类型,某些具有类型推导能力的现代语言可能能够部分减轻这个要求。

动态类型语言:在运行时确定数据类型的语言。变量使用之前不需要类型声明,通常变量的类型是被赋值的那个值的类型。

强类型语言:一旦变量的类型被确定,就不能转化的语言。实际上所谓的貌似转化,都是通过中间变量来达到,原本的变量的类型肯定是没有变化的。

弱类型语言:一个变量的类型是由其应用上下文确定的。比如语言直接支持字符串和整数可以直接用 + 号合并,如JS。
:强弱类型其实也是一个相对概念,一般按照内存中存储时有没有数据类型进行分类,但很多语言在语法上其实是禁止泛类型操作的,实际应用中,不论是采用何种语言,都应尽量避免不同类型的变量直接进行操作,以免产生bug。
在这里插入图片描述

二、计算机中的原码、反码与补码

在计算机内存中,数字都是以二进制的形式储存的,对于整数来说,因为有符号正负的区别,所以规定将一串表示整数的二进制码的第一位表示符号,0为正,1为负,如01111111表示十进制的127,但全部使用原码出现两个问题:①+0与-0的表示码不同;②减法运算(即正数+负数)会出现错误,由于CPU的硬件结构中只有加法器,所以需要一种对整数的表示和运算方式来解决这个问题。

补码的设计目的:简化运算规则,提高运算效率,并使符号位也参与运算。

原码:符号位+绝对值;

反码(用于计算补码):正数的反码为其本身,负数的反码为符号位不变,其余各位取反;

补码(用于解决问题):正数的补码为其本身,负数的补码为符号位不变,在反码的基础上+1(这只是补码的计算方法),补码的原理即取同模正数加符号位,即相当于(模数-绝对值)加符号位,在二进制中的表示即去除符号位后取反+1;

模的概念:将一个单位称为模/模数,如以12为模,则所有的-2都可以同化为+10,即10和-2对模12而言互为补数。

例如:设字长为8的两个二进制数10,111,111/00,111,111,其十进制为-63与+63;则其反码表示为11,000,000/00,111,111,十进制为-64与+63;补码表示为11,000,001/00,111,111,为-65与+63(即对其原码取同模正数加符号位)。

补码运算的原理
(1) +0与-0的补码由于溢出的关系都为00,000,000(解决了0在运算中的表示码不同问题,并且因为溢出,所以可以将10,000,000(原本的-0)表示-128,处理了±0的问题并增加了表示范围);

(2) 同样是活用溢出,将减法等价于+(负数)等价于+(同模正数)-(模数),即4-2=4+(-2)=4+(8-2)-8;

(3) 所以补码其实就是对原码取同模,小于模数的正数无需取同模因此其补码为自身,负数的加法运算需要等价于(+同模正数-模数)并处理符号位,进行以下考虑:
①字长固定,即溢出后的值不计;
②首位表示符号,但后续溢出后会进位到符号位;
③普通加法可能的结果有(用a表示正数b表示负数,m表示该字长的模数):Ⅰ a+a<m;Ⅱ a+a≥m;Ⅲ a+b>0;Ⅳ a+b<0;Ⅴ b+b≤-m;Ⅵ b+b>-m,其中ⅠⅥ类型没有出现符号位的变化因此可以不予考虑。

首先考虑Ⅱ,即两个正数相加溢出的情况,假设字长为4,则除符号位之后只有3位用于表示二进制数,设两个正数都为111(7),则其相加为1110(14),溢出到符号位上1,由于已经溢出且已经限定字长,所以不应该仍能表示为正数,但也应该记录其信息,所以比较好的做法就是将符号位上0表示为正,1表示为负,则两个0111(+7)相加的结果为1110(-6),不要忘记现在在用补码来运算,1110对应的原码是1010(-2),与14同模,相当于14-2*8(8为模数);

Ⅴ的情况与Ⅱ类似,两个负数相加溢出时,也应该能记录其信息,解决方法也相同,两个1111(-7)相加的结果为11110(其原码为00010),去除溢出的位后为0010(+2),与-14同模,相当于-14+2*8(8为模数);

考虑Ⅲ, Ⅳ,即正数+负数的情况,常规思路下即比较两者绝对值,哪个大则符号就依照哪个,但这里要进行加法运算,因此对负数取同模,则负数绝对值小时其同模补码绝对值大,负数绝对值大时其同模补码绝对值小,再与正数相加,产生的情况为:当负数的同模补码绝对值大时符号位溢出,当负数的同模补码绝对值小时符号位不溢出,刚好与正负数加法的符号位对应;
例如:以8为模,7+(-1),-1的同模补码为7(其符号位为负),7+7=14(符号位从1溢出为0),去除溢出取补码后为6;
1+(-7),-7的同模补码为1(符号位为负),1+1=2(符号位不溢出为1),其结果为-2,取原码后为-6;

(4) 因此将0表示正数,将1表示负数,这样可以做到两个数相加时:
①若都为正则溢出为负数(溢出值=两者之和-模*2),若都为负则溢出后为正数;
②正负相加看绝对值,因此如果正数足够大,则大概率溢出,使结果符号位变为0;而对于负数来说,绝对值小的负数补码真值大,绝对值大的负数补码真值小,因此如果负数绝对值小,则补码真值大,符号位大概率溢出为0;如果负数绝对值大,则补码真值小,一种可能为不溢出符号位为1,另一种可能是溢出,即正数的补码真值足够大,符号位溢出为0。

总结:补码的运算即活用了模的概念,使符号位参与运算(溢出位在其他位置记录与此次运算无关),简化了运算规则提高了运算效率并增大了表示范围。

三、计算机编码的字符与字节

字符与字节:一个字符不等价于一个字节,字符是人类能够识别的符号,而这些符号要保存到计算的存储中就需要用计算机能够识别的字节来表示。一个字符往往有多种表示方法,不同的表示方法会使用不同的字节数。这里所说的不同的表示方法就是指字符编码,在文件中,字符是以字节的形式来保存的,Unicode才是真正的字符串,utf-8/ACSII等字符编码方式都是字节串。

操作系统(Operating System)32位与64位的差异:支持超过4G的内存,支持64位处理器,即处理器一次可以运行64bit数据(且使用指令减少),理论上性能提升1倍。

字符字节比特等
位(bit,比特):存储数据最小单位,二进制的一位,只有两种状态;
字节(byte):一个字节有8bit;
帧(frame):数据链路层的最小传输单元,由设备决定大小,64-1518bytes;
字(字符):由不同的字符编码方式决定单个字符的字节数;
字长:单个字符占的bit数。

编码与解码:Unicode字符编码,是一张字符与十六进制数字(代码点code point)的映射表,即输入文件的字符,统一都是先用Unicode映射表示的,即输入的字符对应的Unicode代码点映射序列才是字符串,这个字符串想要存储在内存中需要表示为一组字节,编码即将这个Unicode代码点映射序列通过特定的表示方式转换为对应的字节串,解码即将字节串转换为对应的Unicode代码点映射序列,其在python解释器与文本编辑器中的机制如图所示。
在这里插入图片描述

python中的字符编码:python3中默认使用Unicode(UCS-2)作为字符串(因此可以直接编码无需解码),其中的每一个字符都占两个字节;每一个字符在Unicode中都有一个整数编码,即ord()返回的值,这个值当字符是ASCII字符集中的字符时与它一样,使用chr()时可以使用十进制整数或16进制整数(0x0031),直接输出时可使用’\uxxxx’,xxxx是十六进制字符编码(即字符与未用其它方式编码的字节串是一一对应的,可以直接以字节形式输出字符串)。
:即在编辑时统一使用Unicode格式,在保存时需要进行指定编码模式编码然后存储起来,若想要进行读取与显示,必须指定解码方式将其解码为Unicode字符串。

读取文件:python中’r’模式读取,有默认参数encoding(gbk),因此读取文件时,是将存储的二进制数据(字节流)读出并用gbk解码,若存储方式不为gbk则解出乱码或报错,应指定encoding参数;’rb’模式读取,是直接读取字节流(存储的二进制数据)不做任何操作,需要操作时可以指定解码方式对其进行解码(但必须与该文件存储时的编码方式对应),可以转为Unicode代码点映射序列,并且根据对应关系显示为相应的字符。

四、学习python的准备工作

python简介:python语言起源于1989年,是一个动态强类型的解释型面对对象脚本语言,创始人Guido van Rossum对python的定位是“优雅”、“明确”、“简单”,应尽量写容易看明白的代码,尽量写少的代码。

python的优缺点:python特点鲜明,在实际运用中应扬长避短,根据其优点来进行开发,可通过help查询python的内置函数、模块等。

(1)优点:①易于使用,语法结构简单,上手容易,并支持高级的数据类型;
②面向对象,易复用;
③解释型语言,无需编译与链接,拥有交互模式,节省开发时间;
④动态类型,变量和参数无需声明即可使用(根据实际应用场景判断其实用性),使用缩进代替了大括号,程序结构紧凑清晰;
⑤拥有丰富的内建库和第三方库,成熟的框架,且程序可扩展,例如可以将C语言的集成进python程序,也可以将python解释器集成进C程序模块,在一定程度上缓解了性能问题;
人工智能与python:①python语法简单上手容易且易阅读,可以让开发者将精力专注于工作本身而非语言上;②python支持很多高级数据结构,无需重新开发;③python集成了C模块,解决了性能瓶颈;当一门支持高级数据结构的高级语言没有了性能瓶颈,那为什么不使用呢~

(2)缺点:①作为解释型语言,运行速度慢;②GIL的存在,假的多线程;③代码不能加密等。

WIN下命令行模式、交互模式和IDLE的区别
(1)命令行模式即CMD,命令提示符,在此中可直接运行.py文件,可输出程序运行结果(若无输出则为空);
(2)交互模式可在命令行模式中输入python3来进入,运行输入的每一行代码并输出结果,多用于调试程序,不可直接在交互模式中打开.py文件,shell即交互模式,在交互式环境中遇到冒号,会自动换行,即可将一个代码组一次输入;
(3)IDLE是一个python自带的简洁的集成开发环境,可进行代码编写。

关于缩进
python中,只使用缩进区分不同级别的代码,因此空格和TAB混用会造成不能识别,因此在编写代码时,建议统一使用4个空格来进行缩进,可采用文本编辑器的附加功能来对空格和缩进符进行检查。(python本身并没有规定用多少个空格来进行区分)

关于注释
(1)单行注释:将‘#’放置在要注释的行前,直到换行为止,可放置于函数语句之后;
(2)多行注释:’’’…’’’一对三引号之中的内容,但要注意在语句中可表示字符串(Python中没有一个单独的多行标记,是因为包含在一对三括号之中且不属于任何语句的内容会被忽略,因此视其为长注释);
(3)编码声明注释:一般在程序的最前声明编码,如# -*- coding:utf-8 -*-,在python3中可省略,因为python3统一默认utf-8编码。

关于脚本文件
首行的#!/usr/bin/env python 意为当作为可执行文件时使用python来执行,常用于linux的脚本文件,其后的-*-coding:utf-8-*-在python3中可以省略。

在编写可能进行交互的代码时注意:
①以需求作为第一要素,可以在完成需求后对需求进行改进,但首先完成的版本必须按照需求进行;
②将用户看作傻X,它可能无视任何提示,输入任何东西,如特殊符号、一堆空格、选项的大小写不分、esc等,严格限制用户的输入可能造成的后果;
③添加边界条件,即用户可能无视设定的边界,继续输入奇怪的东西,如空格、错误的引发选项等,需要对重复输入的错误进行捕捉。

五、python的编码命名规范、保留字等

编写代码规范
1、使用4个空格进行缩进;
2、每行不超过79个字符,可使用()[]{}将其进行隐性连接(使用缩进来保证代码美观),最好不使用’\’进行连行,虽然可行,但不推荐;
在这里插入图片描述
3、使用必要的空行,一般函数、类的定义前可空两行,方法之间可空一行;
4、使用必要的空格,’,’右侧一般使用空格,运算符两侧和函数参数之间使用空格,等号的前后使用空格(关键字参数和默认参数等号两侧不加空格),冒号后使用空格(在切片中按切片规范);
5、注释独占一行;
6、尽量避免在循环语句中使用‘+,+=’运算符累加字符串(会创建不必要的临时对象);
7、尽量避免一次导入多个模块,同一模块的不同类需同时导入;
8、不要在行尾添加分号,不要使用分号将两条命令放在同一行;
9、关于二元运算符,如图所示:
在这里插入图片描述
在这里插入图片描述
10、顶层函数和类前后需空两行(注释不算空行),函数def语句后需空一行(与文档字符串之间),行末不要包含额外的空格,空行中不要有空白符、制表符等空字符。

命名规范
1、包名:尽量短小,全部使用小写字母,不推荐使用下划线,可用’.’;
2、模块、类的属性、函数、方法名:尽量短小,全部使用小写字母,使用下划线来分割(下划线法);
3、类名:Pascal风格(大驼峰法),将每个单词的首字母大写,如BorrowBook;
4、常量:全部使用大写字母,可以使用下划线;
5、变量:第一个字符不能是数字,不能使用保留字。
注:关于更多的编写与命名规范可参考PEP 8 (Python Enhancement Proposal #8),PEP8是一个编码规范,其目的是让程序更具有可读性,其中有很多关于编程风格的建议,但不强制,可以根据项目实际需求灵活处理。

python中的部分常用保留字(参考)
and 用于表达式运算、逻辑与操作
as 用于类型转换
assert 断言,用于判断条件或表达式的值是否为真,用于程序调试
break 中断循环语句,终止当前循环
class 用于定义类
continue 中断循环语句,终止本次循环
def 用于定义函数或方法
del 用于删除变量或序列的值
elif 条件语句,与if、else同用
else 条件语句,与if、elif同用,或用于异常、循环语句
except 用于捕获异常,与try、finally同用
finally 用于捕获异常,与try、except同用
for for循环
from 用于导入模块,与import同用
False 布尔值,假
global 用于定义全局变量
if 条件语句,与else、elif同用
import 用于导入模块,与from同用
in 判断是否在其中
is 判断变量是否为某个类的实例
lambda 定义匿名函数
nonlocal 用于声明外层变量
not 用于表达式运算,逻辑非操作
None 空值
or 用于表达式运算,逻辑或操作
pass 空的类、方法或函数的占位符
raise 用于异常抛出
return 用于从函数返回结果
try 用于异常操作语句,与except、finally同用
True 布尔值,真
while while循环
with 用于对资源进行访问的场合,保证资源的释放和文件的关闭
yield 用于从函数依次返回值
:pip(Package Installer for Python)

python中的基本数据类型
(1)数字
①整数:int,精确值。
②浮点数:float,近似值,是使用二进制模拟出来的近似数,不能精确表示一个浮点数。
③十进制小数:通过Decimal模块实现,精确值,可精确表示一个十进制的浮点数,但有总位数限制,可以使用字符串形式传入一个准确的浮点数,但不能直接传入浮点数(因为其不精确)。
④分数:通过Fraction模块实现,精确值,提供分数相关的运算,注意如果提供一个二进制无法精确表示的浮点数,则可能会返回分子分母都非常大的分数。
⑤复数:用real + image j/J来表示,实部和虚部都是浮点数类型,conjugate()方法可以返回其共轭复数。

(2)字符串:str(string)

(3)容器(序列)
列表:list
元组:tuple
词典:dict(dictionary)
集合:set

(4)布尔值:True,False(使用bool()可以判断布尔值,除了“0,空字符串、列表和None”为False,其他都为True)

(5)空值:None

(6)变量:可以直接赋值无需声明

python中的运算符
(1)算术运算符

+	加
-	减
*	乘
/	除
%	求余,返回除法的余数
//	取整,返回商的整数
**	幂,返回x的y次方

(2)比较运算符 (会返回一个布尔值)

>	大于
<	小于
==  等于(尤其注意区分 ==(等于)与 =(赋值))
!=	不等于
>=	大于等于
<=	小于等于

(3)赋值运算符(x△y :x = x △ y)

=	赋值
+=	加赋值
-=	减赋值
*=	乘赋值
/=	除赋值
%=	求余赋值
**=	幂赋值
//=	取整赋值

:赋值运算符,在对不可变对象进行操作时,是将变量重新赋值,而对可变对象进行操作时,是在原对象上直接操作。

(4)逻辑运算符(两个布尔值的运算,结果仍是一个布尔值)

and	逻辑与(and优先级比or高,表达式从左至右解析,当结果可确定就停止)
or	逻辑或
not	逻辑非(拥有最高优先级)

(5)位运算符(会将输入的整数转换为二进制后再进行运算)

&	位与,两个二进制对应数位都为1时结果数位为1,否则0,精度取高位
|	位或,两个二进制对应数位都为0时结果数位为0,否则1
^	位异或,两个二进制对应数位相同时结果数位为0,否则1
~	位非,将二进制数位上的1改为0,0改为1(~x)
<<	位左移,相当于乘2的n次幂(x<<2),比乘方运算效率高很多,可常用
>>	位右移,相当于除2的n次幂(x>>1)

(6)运算符的优先级

**→~+-(正负号)→*/%//(算术运算符)→+-→<<>>(位左右移)→&(位与)→^(位异或)→|(位或)→比较运算符

一般采用()来限定运算次序,防止产生错误。

:关于python中的运算符操作,如'=='操作,其实是调用了__eq__方法,方法可重写,即可以对一些运算符进行重定义,在定义新的数据结构/独有类时会用到,可以简化操作。

python中的流程控制
(1)if…elif…else:最常用的流程控制,用于选择条件,if和elif后的表达式中可以添加逻辑运算符,其计算表达式的布尔值结果,所有空集、数字0、None、False之外的对象都表示为True,并可简化为r = a if a>b else b此种形式,else可用于while和for语句后,将在同级循环结束后顺序执行,但遇到break后不执行。

(2)while:注意循环条件,可能出现死循环,一般循环次数未知时用while。

(3)for:for 迭代变量 in 对象,其中迭代变量不需定义,对象只要是可迭代对象即可(如range对象,字符串等)。
若担心被迭代对象变化产生异常或出于安全性的考虑,可以制作一个副本来进行迭代(切片,赋值等)。
:一般循环次数已知时用for。

(4)break和continue:用于跳出循环,break跳出当前循环,continue跳出当次循环并开始下一次循环。

(5)range:生成一个整数序列(非列表,是一个生成器对象,被遍历之后就不存在,包括for,list等),range(a,b,c)其中a是起始值默认为0,b是结束值不能省略(生成的序列中不包括此值),c用于指定步进值(必须3个参数全部存在时,最后一个才代表步进值)。

(6)pass:空,起占位作用。

:在循环中的赋值符号,若重新赋值则其与循环外的变量很有可能不同。




小结:本文总结了个人在学习python之初的基础语言结构了解和对于一些原理性内容的简单整理,有部分内容相对艰深,可能总结的也不是很到位,如有错漏请提出,共同学习,共同提高。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值