01_python基础(一)
python学习笔记,打算用五章介绍完python基础语法及基本用法。
开发环境: python3.7 推荐: https://github.com/jackfrued/Python-100-Days python基础语法学习不错。
编码规范:
PEP 8风格指南
PEP是Python Enhancement Proposal的缩写,通常翻译为“Python增强提案”。每个PEP都是一份为Python社区提供的指导Python往更好的方向发展的技术文档,其中的第8号增强提案(PEP 8)是针对Python语言编订的代码风格指南。尽管我们可以在保证语法没有问题的前提下随意书写Python代码,但是在实际开发中,采用一致的风格书写出可读性强的代码是每个专业的程序员应该做到的事情,也是每个公司的编程规范中会提出的要求,这些在多人协作开发一个项目(团队开发)的时候显得尤为重要。我们可以从Python官方网站的PEP 8链接中找到该文档,下面我们对该文档的关键部分做一个简单的总结。
空格的使用
- 使用空格来表示缩进而不要用制表符(Tab)。这一点对习惯了其他编程语言的人来说简直觉得不可理喻,因为绝大多数的程序员都会用Tab来表示缩进,但是要知道Python并没有像C/C++或Java那样的用花括号来构造一个代码块的语法,在Python中分支和循环结构都使用缩进来表示哪些代码属于同一个级别,鉴于此Python代码对缩进以及缩进宽度的依赖比其他很多语言都强得多。在不同的编辑器中,Tab的宽度可能是2、4或8个字符,甚至是其他更离谱的值,用Tab来表示缩进对Python代码来说可能是一场灾难。
- 和语法相关的每一层缩进都用4个空格来表示。
- 每行的字符数不要超过79个字符,如果表达式因太长而占据了多行,除了首行之外的其余各行都应该在正常的缩进宽度上再加上4个空格。
- 函数和类的定义,代码前后都要用两个空行进行分隔。
- 在同一个类中,各个方法之间应该用一个空行进行分隔。
- 二元运算符的左右两侧应该保留一个空格,而且只要一个空格就好。
标识符命名
PEP 8倡导用不同的命名风格来命名Python中不同的标识符,以便在阅读代码时能够通过标识符的名称来确定该标识符在Python中扮演了怎样的角色(在这一点上,Python自己的内置模块以及某些第三方模块都做得并不是很好)。
- 变量、函数和属性应该使用小写字母来拼写,如果有多个单词就使用下划线进行连接。
- 类中受保护的实例属性,应该以一个下划线开头。
- 类中私有的实例属性,应该以两个下划线开头。
- 类和异常的命名,应该每个单词首字母大写。
- 模块级别的常量,应该采用全大写字母,如果有多个单词就用下划线进行连接。
- 类的实例方法,应该把第一个参数命名为
self
以表示对象自身。 - 类的类方法,应该把第一个参数命名为
cls
以表示该类自身。
表达式和语句
在Python之禅(可以使用import this
查看)中有这么一句名言:“There should be one-- and preferably only one --obvious way to do it.”,翻译成中文是“做一件事应该有而且最好只有一种确切的做法”,这句话传达的思想在PEP 8中也是无处不在的。
- 采用内联形式的否定词,而不要把否定词放在整个表达式的前面。例如
if a is not b
就比if not a is b
更容易让人理解。 - 不要用检查长度的方式来判断字符串、列表等是否为
None
或者没有元素,应该用if not x
这样的写法来检查它。 - 就算
if
分支、for
循环、except
异常捕获等中只有一行代码,也不要将代码和if
、for
、except
等写在一起,分开写才会让代码更清晰。 import
语句总是放在文件开头的地方。- 引入模块的时候,
from math import sqrt
比import math
更好。 - 如果有多个
import
语句,应该将其分为三部分,从上到下分别是Python标准模块、第三方模块和自定义模块,每个部分内部应该按照模块名称的字母表顺序来排列。
python的关键字
import keyword print(keyword.kwlist) print(len(keyword.kwlist))
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
35
python内置函数 BIF:(built-in functions)内置函数
#!/usr/bin/env python3.7 # -*- coding:utf-8 -*- # Author: Lancer 2019-09-02 10:07:21 import math # abs() 函数返回数字的绝对值 print(abs(-8)) # divmod() 函数把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b) print(divmod(9, 2)) # input() 函数接受一个标准输入数据,返回为 string 类型 # a = input("input:") # print(a) # open() 函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写 # staticmethod() 返回函数的静态方法。 # all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE,如果是返回 True,否则返回 False。 # enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中 seasons = ['Spring', 'Summer', 'Fall', 'Winter'] print(list(enumerate(seasons)) ) # int() 函数用于将一个字符串或数字转换为整型。 print( int('0xa',16) ) #ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值, #如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError 的异常 print(ord('c')) # str() 函数将对象转化为适于人阅读的形式 dict_test = {'runoob': 'runoob.com', 'google': 'google.com'} print(str(dict_test)) # any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,则返回 False,如果有一个为 True,则返回 True print(any(['a', 'b', 'c', 'd'])) # eval() 函数用来执行一个字符串表达式,并返回表达式的值 x = 7 print(eval( '3 * x' )) # isinstance() 函数来判断一个对象是否是一个已知的类型,类似 type() print(isinstance (x,int)) # pow() 方法返回 xy(x的y次方) 的值 print( pow(2,5)) # sum() 方法对系列进行求和计算 print(sum([5,6,8])) # basestring() 方法是 str 和 unicode 的超类(父类),也是抽象类,因此不能被调用和实例化,但可以被用来判断一个对象是否为 str 或者 unicode 的实例 # isinstance(obj, basestring) 等价于 isinstance(obj, (str, unicode))。 print(isinstance("Hello world", str)) # execfile() 函数可以用来执行一个文件。 execfile('hello.py') # issubclass() 方法用于判断参数 class 是否是类型参数 classinfo 的子类。 class A: pass class B(A): pass print(issubclass(B,A)) # print() 方法用于打印输出,最常见的一个函数。 print 在 Python3.x 是一个函数,但在 Python2.x 版本不是一个函数,只是一个关键字。 ''' super() 函数是用于调用父类(超类)的一个方法。 super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。 MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。 ''' #bin() 返回一个整数 int 或者长整数 long int 的二进制表示 print(bin(255)) # file() 函数用于创建一个 file 对象,它有一个别名叫 open(),更形象一些,它们是内置函数。参数是以字符串的形式传递的。 # iter() 函数用来生成迭代器。 lst = [1, 2, 3] for i in iter(lst): print(i) #Python len() 方法返回对象(字符、列表、元组等)长度或项目个数。 print(len(lst)) #python range() 函数可创建一个整数列表,一般用在 for 循环中。 range(start, stop[, step]) #type() 函数如果你只有第一个参数则返回对象的类型,三个参数返回新的类型对象。 # property() 函数的作用是在新式类中返回属性值。 # Python 元组 tuple() 函数将列表转换为元组。 print(tuple([1,2,3,4])) # bool() 函数用于将给定参数转换为布尔类型,如果没有参数,返回 False。 bool 是 int 的子类。 # filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。 ''' class bytearray([source[, encoding[, errors]]]) 如果 source 为整数,则返回一个长度为 source 的初始化数组; 如果 source 为字符串,则按照指定的 encoding 将字符串转换为字节序列; 如果 source 为可迭代类型,则元素必须为[0 ,255] 中的整数; 如果 source 为与 buffer 接口一致的对象,则此对象也可以被用于初始化 bytearray。 如果没有输入任何参数,默认就是初始化数组为0个元素。 bytearray() 方法返回一个新字节数组。这个数组里的元素是可变的,并且每个元素的值范围: 0 <= x < 256。 ''' print(bytearray([1,2,3]), bytearray('runoob', 'utf-8') ) # float() 函数用于将整数和字符串转换成浮点数。 # ist() 方法用于将元组转换为列表。 aTuple = (123, 'xyz', 'zara', 'abc') print(list(aTuple)) # python raw_input() 用来获取控制台的输入。 raw_input() 将所有输入作为字符串看待,返回字符串类型。 # unichr() 函数 和 chr()函数功能基本一样, 只不过是返回 unicode 的字符。 # callable() 函数用于检查一个对象是否是可调用的。如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。 # Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。 基本语法是通过 {} 和 : 来代替以前的 % 。 format 函数可以接受不限个参数,位置可以不按顺序。 # locals() 函数会以字典类型返回当前位置的全部局部变量。 对于函数, 方法, lambda 函式, 类, 以及实现了 __call__ 方法的类实例, 它都返回 True。 # reduce() 函数会对参数序列中元素进行累积。 函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作, # 得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。 # chr() 用一个范围在 range(256)内的(就是0~255)整数作参数,返回一个对应的字符。 print(chr(97)) # frozenset() 返回一个冻结的集合,冻结后集合不能再添加或删除任何元素。 # long() 函数将数字或字符串转换为一个长整型。 # reload() 用于重新载入之前载入的模块。 # vars() 函数返回对象object的属性和属性值的字典对象。 # getattr() 函数用于返回一个对象属性值。 # map() 会根据提供的函数对指定序列做映射。 第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。 # repr() 函数将对象转化为供解释器读取的形式。 # xrange() 函数用法与 range 完全相同,所不同的是生成的不是一个数组,而是一个生成器。 # cmp(x,y) 函数用于比较2个对象,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1。 # lobals() 函数会以字典类型返回当前位置的全部全局变量。 # max() 方法返回给定参数的最大值,参数可以为序列。 print(max(80, 100, 1000)) # reverse() 函数用于反向列表中元素。 aList = [123, 'xyz', 'zara', 'abc', 'xyz'] aList.reverse() print(aList) # zip() 函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。 # compile() 函数将一个字符串编译为字节代码。 # hasattr() 函数用于判断对象是否包含对应的属性。 # memoryview() 函数返回给定参数的内存查看对象(Momory view)。 所谓内存查看对象,是指对支持缓冲区协议的数据进行包装,在不需要复制对象基础上允许Python代码访问 # round() 方法返回浮点数x的四舍五入值。 # __import__() 函数用于动态加载类和函数 。 如果一个模块经常变化就可以使用 __import__() 来动态载入。 __import__(name[, globals[, locals[, fromlist[, level]]]]) # complex() 函数用于创建一个值为 real + imag * j 的复数或者转化一个字符串或数为复数。如果第一个参数为字符串,则不需要指定第二个参数。。 # hash() 用于获取取一个对象(字符串或者数值等)的哈希值。 print(hash('hello') ) # min() 方法返回给定参数的最小值,参数可以为序列。 # set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集、差集、并集等。 # delattr 函数用于删除属性。 # help() 函数用于查看函数或模块用途的详细说明 # next() 返回迭代器的下一个项目。 # setattr() 函数对应函数 getattr(),用于设置属性值,该属性不一定是存在的。 # dict() 函数用于创建一个字典。 print( dict(a='a', b='b', t='t') ) # hex() 函数用于将10进制整数转换成16进制,以字符串形式表示。 print(hex(15)) # slice() 函数实现切片对象,主要用在切片操作函数里的参数传递。 # dir() 函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息。 # id() 函数用于获取对象的内存地址。 # oct() 函数将一个整数转换成8进制字符串。 ''' sorted() 函数对所有可迭代的对象进行排序操作。 sort 与 sorted 区别: sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。 list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。 sorted(iterable, cmp=None, key=None, reverse=False) iterable -- 可迭代对象。 cmp -- 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。 key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。 reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认 ''' a = [5,7,6,3,4,1,2] b = sorted(a) # 保留原列表 print(b)
函数装饰器和闭包
1 装饰器基础知识:
装饰器是可调用对象,其参数是另外一个函数(被装饰的函数),装饰器可能会处理被装饰的函数,然后把他返回,或者将其替换成另一个函数和或者可调用对象。
def deco(func): def inner(): print("running inner") return inner @deco def target(): print("running target()") target() #运行结果:running inner
deco返回inner函数对象,使用deco装饰target, 调用被装饰的target其实会运行inner。严格来说,装饰器只是语法糖,装饰器可以像常规的调用对象那样调用,其参数是另一个函数。
上文中 @deco 等价于 deco(target)
装饰器特性 1 能把被装饰的函数替换为其他函数 2 装饰器在加载模块时候立即执行,被装饰的函数只在明确调用时运行。
2 变量作用域规则
b = 6 def f2(a): print(a) print(b) b = 9 f2(3) ''' Traceback (most recent call last): File "作用域.py", line 12, in <module> f2(3) File "作用域.py", line 9, in f2 print(b) Unboun
实际python编译函数的定义体时,它判断b是局部变量,因为函数体中给它赋值了,生成字节码证实了这种判断,python会尝试从本地环境获取b。如果函数体中赋值想让解释器把b当成全局变量,
要用global声明。
b = 6 def f2(a): global b print(a) print(b) b = 9 f2(3) print(b) ''' 3 6 9 '''
3 闭包:
4 对象引用
pipixia = {"name":"pipi01", "age":18} dapipixia = pipixia print(dapipixia is pipixia) print(id(pipixia),id(dapipixia)) pipixia["eating"] = "yes" print(dapipixia) eq_pipixia = {'age': 18, 'eating': 'yes', 'name': 'pipi01'} print(pipixia == eq_pipixia) print(pipixia is eq_pipixia) ''' True 60536520 60536520 {'age': 18, 'eating': 'yes', 'name': 'pipi01'} True False '''
dapipixia 就是pipixia别名,id()类似C语言地址,具有唯一性。 ==比较值 ,is比较对象标识(id()返回对象标识的整数表示)。