Python的条条框框
-
了解编程语言的分类
-
从运行角度的分类
从运行角度来看,编程语言的类型可以分为两种:编译型和解释型。
Python属于解释型语言。
-
解释型语言:
代码可以直接运行。当然,这也是依赖于附加程序(解释器)来实现的。解释器会不断地循环一组动作:取一行源程序,将其转成二进制指令,然后执行。一直下去,知道全部的源程序读取完毕。类似这样的语言还有JavaScript,VBScript,Perl等;
-
编译型语言:
代码本身不能运行,需要一个附加成秀(编译器)将其转换成二进制代码组成的可执行文件,然后才可以运行。例如C/C++,VB等;
-
解释型语言和编译型语言最大的区别是:
- 解释型语言的代码必须依赖于解释器才可以执行;
- 编译型语言的代码生成可执行程序后,可以独立执行。
- 也有一些附属的打包程序,可以将解释型语言的代码打包称为独立执行的程序。但总体来讲使用打包程序的效率及性能会略慢于编译型语言生成的程序。
-
-
从形态角度的分类
从形态角度来看,编程语言的类型可以分为两种:动态语言和静态语言。
Python属于动态语言。
-
动态语言:
是指程序运行时可以改变其结构,可以对变量或函数进行修改。因为程序中的代码是在可运行时才开始检查数据类型,所以没有运行的语句是被程序忽略的。即,定义变量类型时不需要指定数据类型,只有在第一次给变量赋值时,根据赋值的类型在内部指定该变量的类型。类似的语言还有Perl、Ruby等;
-
静态语言:
常用于编译型语言,在编译时需检查数据的类型。即,在使用变量之前必须要定义好数据类型:如:C,Java等。
-
-
语义角度的编程语言分类
从语义角度来看,编程语言的类型可以分为两种:强定义类型和弱定义类型。
Python属于强定义类型。
-
强定义类型语言:
会严格区分内部的变量类型。一旦指定了变量的类型,就必须经过转换才能存取为其他类型。类似的语言有C,Java等。
-
弱定义类型语言:
是指不严格区分内部的变量类型,一般只要大小放得下即可转化。类似的语言有汇编语言,VBScript,JavaScript等。
-
- Python是一种动态解释型的强定义类型语言。
- 优点是:代码简洁,可读性强,开发效率比较高,可移植性好,可拓展性好,可嵌入性好;
- 缺点是:运行时的性能相对较低,源代码不能加密。
-
-
基础规则
对于一个python项目,它的代码部署路径与代码内容也是息息相关的,这里面设计代码文件,模块,包的相关概念及使用规则。下面分别介绍:
-
了解python源代码相关的几个概念
使用python语言编写源代码,从粗到细可以分为模块文件,代码块,代码三部分。代码里又有“函数”和“类”两种概念。
- 模块文件:是指封装好的代码文件,可作为独立的模块被其他程序引用。
- 代码块:可以理解为一个容器,其中可放置一条一条语句。一个模块文件,一个函数体,一个类,交互式命令中的单行代码,都可以称作一个代码块。
- 代码中的函数:在一个模块文件中,将若干条语句封装在一个代码块里以完成某个独立的功能,供其他程序使用。代码块是通过模块文件来承载的。
- 代码中的类:以面向对象思想,将变量及函数封装成具有某个类别特性的结构体。它可以模块文件的形式单独提供,也可与本地程序一起放在相同的代码文件中。
-
语句的基本规则:变量、语句、代码块
python语句的运行是在python解释器中实现的。错误的python语句不能被解释器所执行。具体的语句规则如下:
-
变量的命名
可以使用字符数字和下划线的组合,首字母可以是字母或者下划线。例如下面的名字都是合法的:
Code、_date、_name_、tt
-
语句区分
在python解释器中,源代码是一行一行被解释执行的,行与行之间通过换行符号来区分。默认是一行一条语句,如果在一行中放油多条语句可以通过 “ ; ” 来区分。例如:
A=6 #一行就是一条语句 B=8;CC=10 #这种属于两条语句,虽然在一行,但是使用分号分开了
-
代码块
通过缩进来表述“代码块”,即同一个代码中的语句具有相同的缩进格式。缩进可以是使用空格或者是Tab键来实现。代码块的概念有点抽象,可以通过下面的例子来理解:
def fun(): #定义一个函数名字叫作fun print("hello fun") #该语句被缩进,表示fun的函数体,只有执行函数fun时才被执行 print("hello main") #该语句没被缩进,直接执行 fun() #该语句没被缩进,会执行其函数体内的语句
上面的代码是一个函数的定义及调用。
第一行代码为函数定义,第二行代码为函数fun的代码块内容。程序运行时,会先执行第三行代码,输出“hello main”,接着执行第四行代码,调用函数fun,输出“hello fun”。
-
-
添加注释
英文字符 “ # ” 用来代表注释。它的生效范围是“行”,即在一行代码中#之后的内容将不被python解释器处理。
注释一般用来说明代码的具体含义,以方便开发人员阅读。另外,也可以用来控制程序暂时不执行某一部分代码块。例如:
#print("hello main")
上面的代码就不会被执行。
在Spyder中,还可以使用快哦接操作快速批量添加或删除注释。
另外也可以使用三个单引号(‘’‘)或者三个双引号(“”“)将代码段变为字符串,程序同样不会执行。例如:
''' #开始 def fun(): print("hello fun") print("hello main") fun() ''' #结束
上面的代码被一对三个单引号所组成的语句包围,系统会认为这时一个字符串,不会将其当作语句来执行
-
使用python的”帮助“
在python中使用help命令来获取帮助信息。它可以查找关于python的基础函数,类型,常用库等信息。例如:
help(print) #显示print函数的帮助信息
输出如下信息:
输出的信息中,描述了print函数的说明,定义,参数的意义。开发者拿到这个信息,就可以按照参数的说明来使用函数了。
-
-
代码文件的结构
python的文件结构可以分为代码,模块,包。
代码是组成程序的基本单位,是一条一条的具体语句。代码的载体是文件。python中的代码文件是以.py结尾的。
-
模块
在实现一个复杂程序时,需要编写的代码量往往很庞大。将所有的代码都放在一个文件里,显然很不合适。这时就需要将代码分割成多个文件,每个文件中放置功能相对独立的代码。在使用时,同时将多个文件中的代码导入到当前代码文件中,以实现完整的功能。这种被裁分后的仍具有独立功能的代码文件就是模块(Module)。
概括地说,模块就是一个支持导入功能的,以.py结尾的代码文件。
-
包
当模块足够庞大时,维护起来不太方便。这就需要使用包(Package)。包可以把多个模块的(.py文件)放在同一个文件夹中,以便于归类与管理。
概括地说,包就是放置模块的文件夹。
在每个包文件夹里都必须包含一个_init_.py文件。该文件的作用是,告诉python环境该文件夹是一个包。_init_.py可以是一个空文件。
-
-
模块的详细介绍
python模块的(Modle)包含了python对象定义和python语句。在模块里可以定义函数、类和变量。模块也能包含可执行的代码。
把相关的代码分配到一个模块里,可以使代码更好用、更易懂。养成使用模块的习惯,开发者能更有逻辑地组织自己的python代码段。
-
模块的作用及分类
模块的主要作用是,用来被导入到其他代码模块中。将其他模块导入(import)到当前模块,可以理解成是对当前模块的一种功能增强。
不同的模块中的函数名和变量名可以是相同的。模块的使用,便面临庞大代码量中函数名和变量名冲突的问题。另外,将代码模块化也提高了代码的可维护性和重用性。
python中的模块可以分为内置模块、自定义模块和第三方模块三类
- 内置模块:python中本来就有的模块;
- 自定义模块:自己开发的模块
- 第三方模块:需要单独下载、安装并导入的模块。
-
模块的基本使用方法
模块使用起来非常简单,使用”import 模块名字“(中间有空格)即可将模块导入。下面引入一个内置的time模块,以显示当前的时间:
import time #引入time模块 print(time.time()) #获取当前时间 print( time.localtime(time.time()).tm_year) #将当前时间格式化
对于内置模块和以及安装好的第三方模块,系统会自动在内置或已经配置好的模块路径下查找该模块,并载入。
-
模块的搜索路径
自定义模块,还需要考虑模块所在的位置,要结合”包名“一起引入。具体语法是:
import 包名.模块名
例如想要在main.py 中导入work下面的train.py模块,需要如下写法:
import work.train
当导入名为train的模块时,解释器会先尝试从内置模块匹配;如果没找到,将在sys.path记录的所有目录中搜索train.py文件。变量sys.path是一个字符串列表,它为解释器指定了模块的搜索路径、sys.path包括:
- 当前程序所在目录;
- 标准库的安装目录;
- 操作系统环境变量PythonPATH所包含的目录;
在编写代码时,可以通过列表操作来对sys.path进行读写,例如:
import sys #引入sys库 print(sys.path) #将sys.path打印出来 sys.path.append('d://lib//Python') #在sys.path里添加一条路径
通过代码对sys.path进行修改,减少了Python程序对环境的依赖,为部署提供了便利。
对sys.path的修改,只在本次程序内有效,系统并不会将sys.path永久保存。如想永久生效,还需对环境变量里进行配置。
-
模块的属性
模块除了被引用以外,还会有自己的属性可供调用者查看。其属性大致有如下几种:
_name_:名字 _doc_:详细说明,介绍了该模块的使用方法 _package_:所在的包名 _loader_:加载的类名 _spec_:简介,介绍了该模块的名字,加载类名,来源类型等概要信息。
要想查看这些属性的内容,可以通过”导入的模块名+.+具体的属性变量“,例如:
import time print(time._name_) #模块名字。输出time
-
模块名字的可变性
在python中,模块的名字属性会根据不同的使用场景发生变化。当模块被导入到其他模块时,_ name _的值为模块本身的名字;而当该模块自己独立运行时, _ name _的值会变为” _ main _“。例如
-
新建一个test1.py文件,写入如下代码:
print(_name_) #将当前模块的名称打印出来
-
新建一个test2.py文件,写入如下代码:
import test1 #导入test1模块
-
运行test1.py文件,输出如下:
_name_ #输出模块名
-
运行test2.py文件,输出如下:
test1 #输出模块名
-
-
模块的常规写法
python程序中,每一个代码文件在可以独立运行的同时,也可以作为一个模块文件。编写模块文件的好习惯是,在编写该模块提供的函数或类的同时,也可以把自身当作独立运行的文件来为自身模块做单元测试。这就需要借助模块名字属性的可变特性来实现了。
例如,可以在模块的最下面加入名字的判断,并执行单元测试代码:
if _name_ == '_main_'; 执行单元测试代码
这样,当直接运行这个模块文件时,可以通过测试代码来检验所定义的函数的输入和输出是否正确。而引入模块时,测试代码不会被执行。为模块编写对应的单元测试代码,是一个非常好的编程习惯。
-
-
模块的四种导入方式
根据所要引入的模块的内容不同,可以将模块的导入方式分为四种。
-
import as方式
import as的方式其实是实现了两步操作:先将模块导入,再为模块重命名。其写法如下:
import a as b
其中,a代表要引入的模块,b是将a重命名后的名称。即,将模块a导入,并将其重命名为b。
举例如下:
import time as x #导入模块time并将其重命名为x s = x.ctime() #调用模块time中的ctime函数,得到当前时间 print(s) #将时间输出
把引入的time模块重命名为x,后面就可以使用x来调用time模块,并调用其ctime方法以获得当前的时间
-
from import方式
from import方式是直接把模块内的函数或变量的名称导入当前模块。其写法如下:
from a import func
上述代码表示,将模块a中的func函数导入到当前模块。使用这种方式导入时,当前模块将只能使用a中的func函数,无法使用a中的其他函数
-
from import *方式
from import *方式将模块中所有的名字(以下划线开头的除外)导入到当前模块符号表里。
具体代码如下:
from time import * #导入模块time中的所有名字(以下划线开头的除外) s = ctime() #直接调用函数 print(s) #将时间输出
使用from import * 方式导入模块的好处是方便,弊端是容易产生名字冲突(如果当前模块里也有个ctime函数,就会跟导入的ctime发生名字冲突)。这是需要注意的地方。
-
导入文件名中带有空格的模块
模块是一个代码文件,而代码文件的命名规范是符合操作系统的命名规则的。在操作系统中允许文件名中出现空格,但是这个规则与Python语法发生冲突,因为在Python中是以空格来隔离一行语句中的不同元素的。在这种情况下,导入带空格的模型会带来麻烦。
解决办法是使用 _ import _方法。假设有个模块叫做“1-1 pyt”,要在当前文件引入时可以写成如下:
pyt = _import_("1-1 pyt")
使用_ import _方法,将模块名称用字符串的方式传入,就可以得到该模块的引用了。
除了模块名字中间带有空格的情况外,如模块名字是以数字开头的,也无法正常导入,需要使用_ import _方法才可以解决这个问题。
-