forked from huweihuang/python-notes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch_plus_index.json
More file actions
1 lines (1 loc) · 57.6 KB
/
Copy pathsearch_plus_index.json
File metadata and controls
1 lines (1 loc) · 57.6 KB
1
{"./":{"url":"./","title":"序言","keywords":"","body":"Python 学习笔记 本系列是 Python 学习笔记 更多的学习笔记请参考: Kubernetes 学习笔记 Golang 学习笔记 Linux 学习笔记 数据结构学习笔记 个人博客:www.huweihuang.com 目录 前言 序言 计算机语言概述 数据类型 数据类型和变量 字符串 list和tuple dict和set 流程控制语句 条件判断 循环 python函数 内置函数 定义函数 函数参数 递归函数 高级特性 切片 迭代 列表生成式 生成器 迭代器 面相对象编程 类和实例 访问限制 继承和多态 获取对象信息 实例属性和类属性 包与模块 包与模块 django 框架 安装Django 创建项目 赞赏 如果觉得文章有帮助的话,可以打赏一下,谢谢! Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-11-22 19:24:57 "},"language.html":{"url":"language.html","title":"计算机语言概述","keywords":"","body":"1. 计算机语言概述 学习一门计算机语言,将计算机语言分为以下几大部分: 语言特点 环境准备 基本语法 数据类型 变量 常量 引用类型 流程语句 判断语句 循环语句 选择语句 函数 面向对象编程 封装(类与方法) 继承 多态(接口) 并发编程 特殊属性 包管理 标准库 2. 思维导图 图片 - 计算机语言 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-09-14 21:42:32 "},"data-type/types.html":{"url":"data-type/types.html","title":"数据类型和变量","keywords":"","body":"1. 数据类型和变量 Python使用缩进来组织代码块,一般使用4个空格的缩进。使用#来注释一行,其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块。Python对大小写敏感。 1.1 整数 Python可以处理任意大小的整数,包括负整数,写法与数学上写法一致,例如:-100。如果用十六进制表示,则用前缀为0x和0-9,a-f表示,例如:0xff00。 1.2 浮点数 浮点数的表示方法:3.14,-9.01。若是科学技术法表示,则10用e代替,例如:1.23$\\times10^9$表示为1.23e9。 整数和浮点数在计算机内存储的方式不同,整数运算永远是精确的(包括除法运算),浮点数运算可能会存在四舍五入的误差。 1.3 字符串 字符串是单引号或双引号括起来的文本。 如果字符串中包含单引号,则用双引号括起来; 如果包含双引号,则用单引号括起来; 如果既包含单引号又包含双引号,则使用转义字符\\来标识,例如:'I\\'m \\\"OK\\\"!'表示的是I'm \"OK\"!。 python中用r''表示''内部的字符串默认不转义,例如print(r'\\\\\\t\\\\')即打印\\\\\\t\\\\。 python中用'''...'''三引号来输入多行内容,其中...是提示符,表示接着上一行输入,例如: >>> print('''line1 ... line2 ... line3''') line1 line2 line3 1.4 布尔值 布尔值只有True和Flase两种(注意大小写,Python对大小写敏感),常用于if的条件判断。 布尔值运算规则如下: and运算是与运算,只有所有都为True,and运算结果才是True。 or运算是或运算,只要其中有一个为True,or运算结果就是True。 not运算是非运算,它是一个单目运算符,把True变成False,False变成True。 1.5 空值 空值是Python里一个特殊的值,用None表示。 1.6 变量 Python中变量类型不固定,即动态语言,不需要提前声明。使用=直接赋值,同一个变量可以反复赋值,且可以是不同类型的变量。例如: a = 123 #a是整数,即a指向整数123 a = \"ABC\" #将a赋值成字符串,即a指向字符串\"ABC\" b = a #将b指向a所指向的数据(\"ABC\") a = \"XYZ\" #将a指向字符串\"XYZ\" print(b) #打印b将打印\"ABC\"而不是\"XYZ\" 变量a=\"ABC\"赋值中,Python解释器处理了以下事项: 在内存中创建一个\"ABC\"的字符串; 在内存中创建了一个名为a的变量,并把它指向\"ABC\"。 把a赋值给b,实际上是将b指向a所指向的数据。 1.7 常量 常量一般用全部大写的变量名表示,例如:PI=3.14。实际上,Python没有机制保证PI的值不会被改变,所以本质仍然是个变量。 Python的除法: /的除法计算结果是浮点数,即使是两个整数相除也是浮点数,例如9 / 3结果为3.0。 //除法只取结果的整数部分,例如10 // 3结果是整数部分3。 %表示取余数,例如:10 % 3结果是余数1。 1.8 总结 Python支持多种数据类型,在计算机内部可以把任何数据看成一个”对象”,而变量赋值就是将变量和数据对象关联起来,即变量指向该数据对象。例如x=y,表示把变量x指向y所指向的数据对象,随后对y的赋值并不影响x的指向。 Python的整数和浮点数没有大小的限制。若超出一定范围就用inf(无限大)表示。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017063826246112 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 20:35:55 "},"data-type/string.html":{"url":"data-type/string.html","title":"字符串","keywords":"","body":"2. 字符串和编码 2.1 字符编码 ASCII编码,早期的编码包含大小写英文字母、数字和一些符号,用一个字节(8位)表示。因编码量少可能会出现乱码问题。 Unicode编码,统一各国语言编码,用两个字节(16位)表示。如果文本全是英文,则会比ASCII编码需要多一倍的存储空间,在存储和传输上不划算。 UTF-8编码,即可变长的Unicode编码,UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码能节省空间。 编码转换工具:https://tool.chinaz.com/tools/unicode.aspx 2.2 字符编码使用场景 在计算机内存中,统一使用Unicode编码。 当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。 例如: 用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。 浏览网页的时候,服务器会把动态的生成的Unicode内容转换为UTF-8再传输到浏览器,所以很多网页的源码上会有类似的信息,表示该网页正是用的UTF-8编码。 2.3 Python的字符串 Python3的版本中,字符串是Unicode编码,即支持多语言。 对于单个字符的编码,Python提供ord()函数获取字符的整数表示,chr()函数把编码转换为对应的字符。例如: >>> ord('A') 65 >>> ord('中') 20013 >>> chr(66) 'B' >>> chr(25991) '文' 如果知道字符的整数编码,可以用十六进制写str: >>> '\\u4e2d\\u6587' '中文' 2.4 字符串(编码)转换 Python的字符串类型是str,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str变为以字节为单位的bytes(UTF-8/ASCII编码)。 Python对bytes类型的数据用带b前缀的单引号或双引号表示: x = b'ABC' 2.4.1 encode()[str→bytes] 以Unicode表示的str通过encode()方法可以编码为指定的bytes,即Unicode编码转换成UTF-8编码或ASCII编码,例如: >>> 'ABC'.encode('ascii') b'ABC' >>> '中文'.encode('utf-8') b'\\xe4\\xb8\\xad\\xe6\\x96\\x87' #错误例子 >>> '中文'.encode('ascii') Traceback (most recent call last): File \"\", line 1, in UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) 2.4.2 decode()[bytes→str] 要把UTF-8编码或ASCII编码转换成Unicode编码,即bytes类型转换为str类型,可用decode()转换。例如: >>> b'ABC'.decode('ascii') 'ABC' >>> b'\\xe4\\xb8\\xad\\xe6\\x96\\x87'.decode('utf-8') '中文' #错误例子 >>> b'\\xe4\\xb8\\xad\\xff'.decode('utf-8') Traceback (most recent call last): ... UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte 如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节: >>> b'\\xe4\\xb8\\xad\\xff'.decode('utf-8', errors='ignore') '中' 2.4.3 len() 对于str类型len()计算的是字符数,对于bytes类型len()计算的是字节数。 #对于str类型 >>> len('ABC') 3 >>> len('中文') 2 #对于bytes类型 >>> len(b'ABC') 3 >>> len(b'\\xe4\\xb8\\xad\\xe6\\x96\\x87') 6 >>> len('中文'.encode('utf-8')) 6 1个中文字符经过UTF-8编码后通常会占用3个字节,而1个英文字符只占用1个字节。 为了避免中文乱码,一般使用UTF-8编码对str和bytes进行转换,即Unicode→UTF-8。所以一般在Python源文件开头写以下信息: #!/usr/bin/env python3 # -*- coding: utf-8 -*- 第一行注释是为了告诉Linux/OS X系统,这是一个Python可执行程序,Windows系统会忽略这个注释; 第二行注释是为了告诉Python解释器,按照UTF-8编码读取源代码,否则,你在源代码中写的中文输出可能会有乱码。 2.5 格式化 2.5.1 %的方式 使用%来格式化字符串,其中%s永远起作用,可以把任何数据类型转换成字符串,如果字符串中包含%,则使用%%转义表示字符串中的%。常用占位符如下: 占位符 替换内容 %s 字符串 %d 整数 %f 浮点数 %x 十六进制整数 例如: >>> 'Hello, %s' % 'world' 'Hello, world' >>> 'Hi, %s, you have $%d.' % ('Michael', 1000000) 'Hi, Michael, you have $1000000.' #整数和浮点数 >>> print('%2d-%02d' % (3, 1)) >>> print('%.2f' % 3.1415926) # %s的通用性 >>> 'Age: %s. Gender: %s' % (25, True) 'Age: 25. Gender: True' #转义字符串中的% >>> 'growth rate: %d %%' % 7 'growth rate: 7 %' 2.5.2 format() 可以使用字符串的format()方法,它会用传入的参数依次替换字符串内的占位符{0}、{1}……。但建议直接使用%的方式。 >>> 'Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125) 'Hello, 小明, 成绩提升了 17.1%' 2.6 json 中的中文解析 使用json.dumps(data, ensure_ascii=False)解析json中的中文。 #!/usr/bin/python # -*- coding: utf8 -*- import json import sys reload(sys) sys.setdefaultencoding('utf-8') data = [ { 'a' : '中文' } ] result = json.dumps(data, ensure_ascii=False) print result 输出结果: [{\"a\": \"中文\"}] 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017075323632896 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-10-16 16:43:26 "},"data-type/list-tuple.html":{"url":"data-type/list-tuple.html","title":"list和tuple","keywords":"","body":"3. list和tuple类型 3.1 list list表示列表,是可变的有序列表,即有序的集合,可以随时添加和删除元素。 3.1.1 list的定义 >>> classmates = ['Michael', 'Bob', 'Tracy'] >>> classmates ['Michael', 'Bob', 'Tracy'] 3.1.2 len() 用len()函数可以获得list元素的个数 >>> len(classmates) 3 3.1.3 list的索引 list元素索引从0开始 索引可以引用负数表示倒数序号,例如classmates[-1]表示倒数最后一个元素,索引-1等价于len(classmates) - 1 索引越界会报IndexError错误,倒序索引也会越界 3.1.4 list元素增删 3.1.4.1 追加末尾元素 >>> classmates.append('Adam') >>> classmates ['Michael', 'Bob', 'Tracy', 'Adam'] 3.1.4.2 指定位置插入元素 >>> classmates.insert(1, 'Jack') >>> classmates ['Michael', 'Jack', 'Bob', 'Tracy', 'Adam'] 3.1.4.3 删除末尾元素 >>> classmates.pop() 'Adam' >>> classmates ['Michael', 'Jack', 'Bob', 'Tracy'] 3.1.4.4 删除指定位置元素 用pop(i)的方法,i为索引值 >>> classmates.pop(1) 'Jack' >>> classmates ['Michael', 'Bob', 'Tracy'] 3.1.4.5 替换元素 即直接给对应索引的元素重新赋值。 >>> classmates[1] = 'Sarah' >>> classmates ['Michael', 'Sarah', 'Tracy'] 3.1.5多维list list中元素的数据类型可以不同,如果要实现二维list,即将一维list中的元素定义为list即可,同理可以实现多维list。例如访问二维list可用s[2][1]的方式,表示一维list中的第三个元素list中的第二个元素。 >>> s = ['python', 'java', ['asp', 'php'], 'scheme'] >>> len(s) 4 3.1.6 空list 空list即一个元素也没有,长度为0。 >>> L = [] >>> len(L) 0 3.2 tuple 3.2.1 tuple的定义 tuple表示元组,即不可变的有序元素的集合。即没有修改元素的函数,例如append(),insert(),元素赋值等。 因为tuple元素不可变,所以代码更安全。当定义tuple时,元素就必须被确定下来。如果tuple中只含一个元素,则在该元素后加逗号。避免与小括号运算产生歧义。 #以下是单元素tuple的定义 >>> t = (1,) >>> t (1,) #以下是小括号运算 >>> t = (1) >>> t 1 3.2.2 特别说明 tuple中的元素不可变表示元素的指向不可变,但该元素如果是list,则该list的内容可变。即list表示的是指向,该list的指向不可变,但是list中元素的指向可变,即list中的元素可变。例如: >>> t = ('a', 'b', ['A', 'B']) >>> t[2][0] = 'X' >>> t[2][1] = 'Y' >>> t ('a', 'b', ['X', 'Y']) 示意图: list元素修改前:t = ('a', 'b', ['A', 'B']) list元素修改后:t = ('a', 'b', ['X', 'Y']) 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017092876846880 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 20:43:52 "},"data-type/dict-set.html":{"url":"data-type/dict-set.html","title":"dict和set","keywords":"","body":"4. dict和set类型 4.1 dict 4.1.1 dict的定义 dict即字典,相当于golang中的map类型,key-value型。具有极快的查找速度。 //dict的赋值 >>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95 //dict元素的赋值 >>> d['Adam'] = 67 由于dict中key的值是唯一的,因此如果多次赋值,最终结果为最后一次的赋值。 4.1.2 dict的查找 如果key不存在会报错,检测key是否存在可以通过in或get()方法。当key不存在时,in的方式返回False,get()方法返回None或指定值。 #key不存在的报错 >>> d['Thomas'] Traceback (most recent call last): File \"\", line 1, in KeyError: 'Thomas' #in方式检查key是否存在 >>> 'Thomas' in d False #get()方法检查key是否存在 >>> d.get('Thomas') >>> d.get('Thomas', -1) -1 4.1.3 dict的删除 要删除dict中的元素,可以通过用pop(key)方法,删除该key对应的键值对。 >>> d.pop('Bob') 75 >>> d {'Michael': 95, 'Tracy': 85} 4.1.4 特别说明 dict的特点: 查找和插入的速度极快,不会随着key的增加而变慢; 需要占用大量的内存,内存浪费多。 dict的key必须是不可变对象,在Python中,字符串、整数等都是不可变的,而list是可变的,就不能作为key。 对比list的特点: 查找和插入的时间随着元素的增加而增加; 占用空间小,浪费内存很少。 4.2 set set表示无序和无重复元素的集合,与数学意义上的集合类似,也可以看成是只有key没有value的dict。 4.2.1 set的定义 要创建一个set,需要提供一个list作为输入集合,如果list中有重复元素则自动过滤掉。 >>> s = set([1, 2, 3]) >>> s {1, 2, 3} #如果有重复元素会自动过滤掉 >>> s = set([1, 1, 2, 2, 3, 3]) >>> s {1, 2, 3} 4.2.2 set的添加和删除 通过add(key)方法可以添加元素到set中,可以重复添加,但无效。 >>> s.add(4) >>> s {1, 2, 3, 4} >>> s.add(4) >>> s {1, 2, 3, 4} 通过remove(key)方法可以删除元素。 >>> s.remove(4) >>> s {1, 2, 3} 4.2.3 set的交集和并集 >>> s1 = set([1, 2, 3]) >>> s2 = set([2, 3, 4]) #交集 >>> s1 & s2 {2, 3} #并集 >>> s1 | s2 {1, 2, 3, 4} 4.3 不可变对象 变量表示一个指向,而变量指向的内容表示一个对象。例如a=\"abc\"中a是变量即指向,而abc是字符串对象。 Python中整数和字符串是不可变对象,而list是可变对象。 >>> a = 'abc' >>> b = a.replace('a', 'A') >>> b 'Abc' >>> a 'abc' 例如上例中,a是变量,abc是字符串对象,当调用a的replace的方法时,实际上是基于原字符串对象重新创建了一个新的字符串对象Abc,而没有改变原字符串对象的内容。 对于不变对象来说,调用对象自身的任意方法,不会改变该对象自身的内容。而会创建新的对象并返回。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017104324028448 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 20:46:13 "},"flow-control/if-else.html":{"url":"flow-control/if-else.html","title":"条件判断","keywords":"","body":"1. 条件语句 1.1 if格式 if : elif : elif : else: 以上是if语句的完整格式,注意事项: Python使用缩进规则,如果if判断条件为true,则执行缩进部分的内容。 if的执行逻辑是从上往下判断,如果某个判断为true,则会忽略剩下的elif和else。 例如:以下例子打印的结果是teenager,即满足第一个if条件则后续判断不再执行。 age = 20 if age >= 6: print('teenager') elif age >= 18: print('adult') else: print('kid') 1.2 条件简写 if x: print('True') 只要x是非零数值、非空字符串、非空list等,就判断为True,否则为False。 1.3 input()使用 s = input('birth: ') birth = int(s) if birth input()返回的数据类型是str,str不能直接和整数比较,必须先把str转换成整数。Python提供了int()函数来转换成整数。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017099478626848 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-09-14 22:10:11 "},"flow-control/for-while.html":{"url":"flow-control/for-while.html","title":"循环","keywords":"","body":"2. 循环语句 2.1 for循环 for...in循环,即把list或tuple中的每个元素迭代出来,执行后续操作。 names = ['Michael', 'Bob', 'Tracy'] for name in names: print(name) Python提供一个range(x)函数,生成0-(x-1)的整数序列。 >>> list(range(5)) [0, 1, 2, 3, 4] //求和运算 sum = 0 for x in range(101): sum = sum + x print(sum) 2.2 while循环 while循环,只要条件满足,就不断循环,条件不满足时退出循环。 sum = 0 n = 99 while n > 0: sum = sum + n n = n - 2 print(sum) 2.3 break 在循环中,break语句可以提前退出循环。 n = 1 while n 10: # 当n = 11时,条件满足,执行break语句 break # break语句会结束当前循环 print(n) n = n + 1 print('END') 2.4 continue 在循环过程中,可以通过continue语句,跳过当前的这次循环,直接开始下一次循环。 n = 0 while n break和continue通常都必须配合if语句使用。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017100774566304 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-09-14 22:10:28 "},"function/library-function.html":{"url":"function/library-function.html","title":"内置函数","keywords":"","body":"1. 内置函数 python的内置参数详见以下链接,也可以通过help(function_name)来查看具体函数的使用帮助。 http://docs.python.org/3/library/functions.html#abs Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice() any() divmod() id() object() sorted() ascii() enumerate() input() oct() staticmethod() bin() eval() int() open() str() bool() exec() isinstance() ord() sum() bytearray() filter() issubclass() pow() super() bytes() float() iter() print() tuple() callable() format() len() property() type() chr() frozenset() list() range() vars() classmethod() getattr() locals() repr() zip() compile() globals() map() reversed() __import__() complex() hasattr() max() round() delattr() hash() memoryview() set() Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:09:13 "},"function/function-def.html":{"url":"function/function-def.html","title":"定义函数","keywords":"","body":"1. 函数的调用 调用函数需要知道函数名和参数,如果传入的参数不对,会报TypeError的错误并且给出错误信息。 1.1 数据类型转换函数 数据类型转换函数可以对数据类型进行转换,例如: >>> int('123') 123 >>> int(12.34) 12 >>> float('12.34') 12.34 >>> str(1.23) '1.23' >>> str(100) '100' >>> bool(1) True >>> bool('') False 1.2 函数引用 函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”: >>> a = abs # 变量a指向abs函数 >>> a(-1) # 所以也可以通过a调用abs函数 1 2. 定义函数 2.1 函数定义 在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。如果没有return语句,函数执行完毕后也会返回结果,只是结果为None。return None可以简写为return。 def my_abs(x): if x >= 0: return x else: return -x 2.2 空函数 如果想定义一个什么事也不做的空函数,可以用pass语句: def nop(): pass pass语句主要用来暂时让程序运行不报错,待后续再补充函数内容。同理,pass还可以用在其他语句里,比如: if age >= 18: pass 2.3 参数检查 调用函数时,如果参数个数不对,Python解释器会自动检查出来,并抛出TypeError。如果要对参数类型进行检查,可以使用内置函数isinstance()实现。例如: def my_abs(x): if not isinstance(x, (int, float)): raise TypeError('bad operand type') if x >= 0: return x else: return -x 2.4 多返回值 import math def move(x, y, step, angle=0): nx = x + step * math.cos(angle) ny = y - step * math.sin(angle) return nx, ny 实际上python的多返回值是一个tuple。只不过按位置依次赋值。 #多返回值 >>> x, y = move(100, 100, 60, math.pi / 6) >>> print(x, y) 151.96152422706632 70.0 #返回值为tuple >>> r = move(100, 100, 60, math.pi / 6) >>> print(r) (151.96152422706632, 70.0) 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017106984190464 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:08:56 "},"function/function-args.html":{"url":"function/function-args.html","title":"函数参数","keywords":"","body":"3. 函数的参数 定义函数的时候,把参数的名字和位置确定下来,函数的接口定义就完成了。对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值,而函数内部的复杂逻辑被封装起来,调用者无需了解。 3.1 位置参数 位置参数,即传入的参数有位置顺序区分。例如以下的x和n根据位置不同,接收对应位置的传入参数。 def power(x, n): s = 1 while n > 0: n = n - 1 s = s * x return s 3.2 默认参数 默认参数,即对某个参数设置默认值,如果没有传入该参数则使用默认值,如果有传入该参数则使用传入值。 必须参数在前,默认参数在后 一般将变化小的参数设置为默认参数,变化大的设置为必选参数 #函数定义 def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s #函数调用 >>> power(5) 25 >>> power(5, 3) 125 有多个默认参数时,可以按顺序提供默认参数,也可以指定默认参数的参数名传值而不按参数顺序。例如: #函数定义 def enroll(name, gender, age=6, city='Beijing'): print('name:', name) print('gender:', gender) print('age:', age) print('city:', city) #按顺序提供默认参数,即7表示age的值 enroll('Bob', 'M', 7) #按参数名提供默认参数,即city值,而没有age的值 enroll('Adam', 'M', city='Tianjin') 注意事项:默认参数必须指向不可变对象,例如整数,字符串,None等。不能指向可变对象,例如list。 #错误示例,默认参数为可变对象list add_end(L=[]): L.append('END') return L #每次调用都会在list中添加元素 >>> add_end() ['END'] >>> add_end() ['END', 'END'] >>> add_end() ['END', 'END', 'END'] 以上例子中,Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。 可改为指向None这个不可变对象来避免该问题。例如: #默认参数指向不可变对象None def add_end(L=None): if L is None: L = [] L.append('END') return L #每次调用恢复原默认值 >>> add_end() ['END'] >>> add_end() ['END'] 3.3 可变参数 可变参数,即待传入的参数的个数是可变的,定义时在参数前面加个*,例如*number。可变参数在函数调用时实际上是一个tuple。 #定义可变参数 *number def calc(*numbers): sum = 0 for n in numbers: sum = sum + n * n return sum #函数调用 >>> calc(1, 2) 5 >>> calc() 0 #已存在list待传入 >>> nums = [1, 2, 3] >>> calc(nums[0], nums[1], nums[2]) 14 #通过list方式出传入可变参数 >>> nums = [1, 2, 3] >>> calc(*nums) 14 3.4 关键字参数 关键字参数,即可以传入0个或任意个含参数名的参数,关键字参数在函数调用时实际上是一个dict。 关键参数定义时在参数前面加**,例如**kw。 #定义关键字参数 def person(name, age, **kw): print('name:', name, 'age:', age, 'other:', kw) #传入必选参数 >>> person('Michael', 30) name: Michael age: 30 other: {} #传入可选的关键字参数 >>> person('Adam', 45, gender='M', job='Engineer') name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'} #使用dict方式传入关键字参数 >>> extra = {'city': 'Beijing', 'job': 'Engineer'} >>> person('Jack', 24, **extra) name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'} 通过dict方式传入实际上是传入一份拷贝,函数参数的改变并不会影响到函数外原dict的值。 3.5 命名关键字参数 通过对关键字参数命名的方式限制只能传入指定名字的关键字参数,而不能传入其他参数。命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数。例如: #定义命名关键字参数 def person(name, age, *, city, job): print(name, age, city, job) #命名关键字参数的调用 >>> person('Jack', 24, city='Beijing', job='Engineer') Jack 24 Beijing Engineer 命名关键字参数必须传入参数名,如果没有传入参数名,调用将报错。 >>> person('Jack', 24, 'Beijing', 'Engineer') Traceback (most recent call last): File \"\", line 1, in TypeError: person() takes 2 positional arguments but 4 were given 命名关键字参数可以有缺省值,即默认参数。 #命名关键字参数的缺省值 def person(name, age, *, city='Beijing', job): print(name, age, city, job) #函数调用 >>> person('Jack', 24, job='Engineer') Jack 24 Beijing Engineer 3.6 参数组合 必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数可以组合使用。但参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。 #参数组合的定义 def f1(a, b, c=0, *args, **kw): print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw) def f2(a, b, c=0, *, d, **kw): print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw) #参数组合的调用 >>> f1(1, 2, 3, 'a', 'b', x=99) a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99} >>> f2(1, 2, d=99, ext=None) a = 1 b = 2 c = 0 d = 99 kw = {'ext': None} 通过tuple和dict调用参数组合函数: #f1 >>> args = (1, 2, 3, 4) >>> kw = {'d': 99, 'x': '#'} >>> f1(*args, **kw) a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'} #f2 >>> args = (1, 2, 3) >>> kw = {'d': 88, 'x': '#'} >>> f2(*args, **kw) a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'} 对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017261630425888 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:06:02 "},"function/recursive-function.html":{"url":"function/recursive-function.html","title":"递归函数","keywords":"","body":"4. 递归函数 4.1 递归函数的定义 递归函数即函数在内部调用函数本身(自己调用自己)。 递归的关键点: 递归结束的临界值,通常使用if语句来判断临界值 递归体的递归逻辑 例如,以下是fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n 的递归函数。 #递归函数的定义 def fact(n): if n==1: return 1 return n * fact(n - 1) #计算5的阶乘,递归函数调用细节 ===> fact(5) ===> 5 * fact(4) ===> 5 * (4 * fact(3)) ===> 5 * (4 * (3 * fact(2))) ===> 5 * (4 * (3 * (2 * fact(1)))) ===> 5 * (4 * (3 * (2 * 1))) ===> 5 * (4 * (3 * 2)) ===> 5 * (4 * 6) ===> 5 * 24 ===> 120 4.2 栈溢出问题 在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。 例如: >>> fact(1000) Traceback (most recent call last): File \"\", line 1, in File \"\", line 4, in fact ... File \"\", line 4, in fact RuntimeError: maximum recursion depth exceeded in comparison 4.3 尾递归 解决递归调用栈溢出的方法是通过尾递归优化。尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。 例如: #尾递归函数的定义 def fact(n): return fact_iter(n, 1) def fact_iter(num, product): if num == 1: return product return fact_iter(num - 1, num * product) #计算5的阶乘,递归函数调用细节 ===> fact_iter(5, 1) ===> fact_iter(4, 5) ===> fact_iter(3, 20) ===> fact_iter(2, 60) ===> fact_iter(1, 120) ===> 120 尾递归调用时,如果做了优化,栈不会增长,无论多少次调用也不会导致栈溢出。但实际上大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,因此当没有优化的情况下任何递归函数都存在栈溢出的问题。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017268131039072 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:06:14 "},"advanced/slice.html":{"url":"advanced/slice.html","title":"切片","keywords":"","body":"1. 切片 切片操作(slice),即从list(tuple是一种特殊的list)中获取部分元素。 L[m,n]表示从L[m]~L[n-1]的list。 L[:n]表示从L[0]~L[n-1]的list。 L[m:]表示从L[m]~L[len(L)-1]。 L[-m:]表示倒数m个数的list。 L[m:n:k]表示从L[m:n]list中每k个取一个数组成一个新的list。 L[::k]表示从L中每k个取一个组成新的list。 tuple也是一种list(不可变的list),使用切片操作的结果仍为tuple。 #定义list >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] #切片操作 >>> L[0:3] ['Michael', 'Sarah', 'Tracy'] >>> L[:3] ['Michael', 'Sarah', 'Tracy'] >>> L[1:3] ['Sarah', 'Tracy'] >>> L[-2:] ['Bob', 'Jack'] >>> L[-2:-1] ['Bob'] #定义0-99的list >>> L = list(range(100)) #前10个数每两个取一个 >>> L[:10:2] [0, 2, 4, 6, 8] #所有数,每5个取一个 >>> L[::5] [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95] #tuple的切片操作 >>> (0, 1, 2, 3, 4, 5)[:3] (0, 1, 2) #字符串切片操作 >>> 'ABCDEFG'[:3] 'ABC' >>> 'ABCDEFG'[::2] 'ACEG' 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017269965565856 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 20:50:58 "},"advanced/iteration.html":{"url":"advanced/iteration.html","title":"迭代","keywords":"","body":"2. 迭代 2.1 迭代的概念 迭代:在某类对象的集合中通过遍历的方法来获取元素,对元素执行某项操作。 Python中的可迭代对象有:list,tuple,dict,str等,包括可迭代的自定义类型。 判断一类对象是否可迭代,可以通过collections模块的Iterable类型判断。例如: >>> from collections import Iterable >>> isinstance('abc', Iterable) # str是否可迭代 True >>> isinstance([1,2,3], Iterable) # list是否可迭代 True >>> isinstance(123, Iterable) # 整数是否可迭代 False 2.2 迭代的使用 在Python中,迭代是通过for ... in来完成的。 2.2.1 dict的迭代 >>> d = {'a': 1, 'b': 2, 'c': 3} >>> for key in d: ... print(key) ... a c b dict默认迭代的是key,for key in d。 可以使用for value in d.values()来迭代value。 可以用for k, v in d.items()来迭代key和value。 2.2.2 字符串的迭代 >>> for ch in 'ABC': ... print(ch) ... A B C 2.2.3 迭代的索引 Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身。 >>> for i, value in enumerate(['A', 'B', 'C']): ... print(i, value) ... 0 A 1 B 2 C 2.2.4 多变量迭代 在for中,同时引用多个变量。例如: >>> for x, y in [(1, 1), (2, 4), (3, 9)]: ... print(x, y) ... 1 1 2 4 3 9 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017316949097888 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-04 13:13:58 "},"advanced/list-comprehensions.html":{"url":"advanced/list-comprehensions.html","title":"列表生成式","keywords":"","body":"3. 列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。 一般是通过for … in和range来生成list。 >>> list(range(1, 11)) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> [x * x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] for循环中加if判断 >>> [x * x for x in range(1, 11) if x % 2 == 0] [4, 16, 36, 64, 100] 多层循环 >>> [m + n for m in 'ABC' for n in 'XYZ'] ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ'] 多变量循环 >>> d = {'x': 'A', 'y': 'B', 'z': 'C' } >>> [k + '=' + v for k, v in d.items()] ['y=B', 'x=A', 'z=C'] 可以使用内建的isinstance函数可以判断一个变量是不是字符串。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017317609699776 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 20:53:39 "},"advanced/generator.html":{"url":"advanced/generator.html","title":"生成器","keywords":"","body":"4. 生成器 在Python中,一边循环一边计算的机制,称为生成器:generator。生成器不必创建完整的list,可以在循环中不断推算出后续的元素,从而可以在获取所需元素的同时节省存储空间。 4.1 直接创建generator 创建generator即把列表生成式的[]改成()。 >>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x * x for x in range(10)) >>> g at 0x1022ef630> 一般通过for循环来获取generator的元素,也可以使用next(g)来获取下一个元素。 >>> g = (x * x for x in range(10)) #通过for循环获取元素 >>> for n in g: ... print(n) ... 0 1 4 #通过next()获取元素 >>> next(g) 0 >>> next(g) 1 4.2 通过函数方式创建 通过yield关键字将一个函数变成generator。例如: 函数的定义: def fib(max): n, a, b = 0, 0, 1 while n 生成器的定义: def fib(max): n, a, b = 0, 0, 1 while n 两者的差别在于生成器将函数的print(b)改为yield b。yield可以翻译为生成,即基于某次计算生成某个元素,而不是提前存储了该元素。 函数式的generator一般采用for循环来获取元素,也可以通过next()来获取下一个元素的值,例如: >>> for n in fib(6): ... print(n) ... 1 1 2 3 5 8 如果要获取return的内容,可以捕获StopIteration错误,返回值包含在StopIteration的value中。 >>> g = fib(6) >>> while True: ... try: ... x = next(g) ... print('g:', x) ... except StopIteration as e: ... print('Generator return value:', e.value) ... break ... g: 1 g: 1 g: 2 g: 3 g: 5 g: 8 Generator return value: done 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017318207388128 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 20:54:52 "},"advanced/iterator.html":{"url":"advanced/iterator.html","title":"迭代器","keywords":"","body":"5. 迭代器 5.1 可迭代对象 可以直接作用于for循环的对象统称为可迭代对象:Iterable。主要有: 集合数据类型,如list、tuple、dict、set、str等 generator,包括生成器和带yield的generator function 可以使用isinstance()判断一个对象是否是Iterable对象: >>> from collections import Iterable >>> isinstance([], Iterable) True >>> isinstance({}, Iterable) True >>> isinstance('abc', Iterable) True >>> isinstance((x for x in range(10)), Iterable) True >>> isinstance(100, Iterable) False 5.2 迭代器 可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。 生成器都是Iterator对象,但list、dict、str是Iterable,而不是Iterator。 可以使用isinstance()判断一个对象是否是Iterator对象: >>> from collections import Iterator >>> isinstance((x for x in range(10)), Iterator) True >>> isinstance([], Iterator) False >>> isinstance({}, Iterator) False >>> isinstance('abc', Iterator) False 可以通过iter()函数将Iterable转换成Iterator。 >>> isinstance(iter([]), Iterator) True >>> isinstance(iter('abc'), Iterator) True Python的Iterator对象表示的是一个数据流,可以是无限大的数据流,例如全体自然数。 Iterator的元素是基于计算的,可以理解为惰性的、动态的、长度未知的(元素个数可能无限)。 list、dict、str的元素是基于存储的,可以理解为静态的、长度已知的(元素个数有限)。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017323698112640 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 20:57:24 "},"oop/class.html":{"url":"oop/class.html","title":"类和实例","keywords":"","body":"1. 类和实例 在Python中所有的数据类型都可以视为对象,也可以自定义对象。自定义的对象数据类型即面向对象中的类(Class)概念。类是抽象的模板,实例是具体的对象。 类的定义 Python使用class关键字定义类: class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print('%s: %s' % (self.name, self.score)) 初始化函数 类中使用__init__方法实现构造函数的功能,该函数的第一个参数的self,表示创建的实例本身,调用时传参只需要传入其他参数,不需要传入self参数,使用__init__方法则不能传入空参数。 创建实例 >>> bart = Student('Bart Simpson', 59) >>> bart.name 'Bart Simpson' >>> bart.score 59 类的方法 类内部定义的方法来实现对类内部属性数据的封装,例如例子中的print_score(self)方法。定义一个类的方法除了第一个参数是self外,其他与函数的定义一样,调用方法时self参数不用传入,其他参数正常传入。 方法可以理解为与实例绑定的函数,可以直接访问实例内部的数据。 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017496031185408 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:11:11 "},"oop/public-private.html":{"url":"oop/public-private.html","title":"访问限制","keywords":"","body":"2. 访问限制 实例的变量以__xxx双下划线开头,没有以__双下划线结尾的,则该变量为私有变量,外部一般无法访问。例如:self.__name = name。 如果变量名是双下划线开头、双下划线结尾,__xxx__是特殊变量而不是私有变量。私有变量的方式可以避免外部对实例内部数据的修改,可以做参数检查。 如果需要获取或修改内部的数据,可以增加get和set的方法。例如: class Student(object): #构造函数 def __init__(self, name, score): self.__name = name self.__score = score #get方法 def get_name(self): return self.__name def get_score(self): return self.__score #set方法 def set_score(self, score): #参数检查 if 0 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017496679217440 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:12:15 "},"oop/polymorphism.html":{"url":"oop/polymorphism.html","title":"继承和多态","keywords":"","body":"3. 继承和多态 3.1 继承 #任何类都继承根类object class Animal(object): def run(self): print('Animal is running...') #Dog和Cat继承Animal class Dog(Animal): pass class Cat(Animal): pass #Dog和Cat的调用 dog = Dog() dog.run() cat = Cat() cat.run() #调用结果,继承Animal的run方法 Animal is running... Animal is running... 例子中Dog和Cat类继承了Animal类,因此拥有父类的所有功能。 3.1 方法重写 子类可以对父类的方法进行重写(覆盖),方法名和方法参数都不变,方法的执行体改变。当对子类进行方法调用时是调用子类重写的方法而不是父类的方法。例如: #方法重写 class Dog(Animal): def run(self): print('Dog is running...') class Cat(Animal): def run(self): print('Cat is running...') #重写方法的调用结果 Dog is running... Cat is running... 3.2 多态 在类型系统中,类也可以理解为一种特殊的数据类型,即类是变量类型,而是类的实例是变量名。也可以通过isinstance()函数来判断某实例是否属于某类。例如: b = Animal() # b是Animal类型 c = Dog() # c是Dog类型 >>> isinstance(b, Animal) True >>> isinstance(c, Dog) True #Dog类继承了Animal类, >>> isinstance(c, Animal) True Dog继承了Animal类,因此Dog的实例的数据类型既可以是Dog(子类),也可以是Animal(父类) [Dog是Animal的一种],反之则不行。 多态的示例 #定义一个函数参数为Animal(父类)类型 def run_twice(animal): animal.run() animal.run() #入参为父类Animal >>> run_twice(Animal()) Animal is running... Animal is running... #入参为子类Dog >>> run_twice(Dog()) Dog is running... Dog is running... #入参为子类Cat >>> run_twice(Cat()) Cat is running... Cat is running... #新增一个子类 class Tortoise(Animal): def run(self): print('Tortoise is running slowly...') #入参为子类Tortoise >>> run_twice(Tortoise()) Tortoise is running slowly... Tortoise is running slowly... 通过以上示例可以看出,当函数的参数类型是父类,传入参数为子类的时候,调用的是具体传入的子类的方法。即调用方只管调用,不管具体的细节。细节由具体的运行对象决定,并且可以在不改变外部调用代码的情况下,增加调用实现的具体细节,即开闭原则。 开闭原则 对扩展开放:允许新增Animal子类; 对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。 3.3 鸭子类型 Python是动态语言,在继承上并不需要像静态语言一样传入一个Animal类型或其子类,或者说不要求严格的继承体系。Python的“file-like object”满足“鸭子类型”,即一个对象只要看起来像鸭子,走起路来像鸭子,那它就可以被看做是鸭子。 所以并不需要传入一个Animal的类型或子类,只需要传入一个实现了Animal的run()方法的对象即可,例如: class Timer(object): def run(self): print('Start...') 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017497232674368 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:16:44 "},"oop/self.html":{"url":"oop/self.html","title":"获取对象信息","keywords":"","body":"5. 实例属性和类属性 Python中除了给实例绑定属性外,还可以给类绑定属性,即类属性。类属性归类所有,但该类的所有实例都可以访问到类属性。实例属性的优先级比类属性高,类属性和实例属性一般不使用相同名字,如果同名则实例属性会屏蔽掉类属性。 >>> class Student(object): ... name = 'Student' def __init__(self, name): self.name = name ... >>> s = Student() # 创建实例s >>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性 Student >>> print(Student.name) # 打印类的name属性 Student >>> s.name = 'Michael' # 给实例绑定name属性 >>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性 Michael >>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问 Student >>> del s.name # 如果删除实例的name属性 >>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了 Student 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017594591051072 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:17:59 "},"oop/type-isinstance.html":{"url":"oop/type-isinstance.html","title":"实例属性和类属性","keywords":"","body":"4. 获取对象信息 4.1 type() 判断对象的类型可以使用type()函数,对象包括基本的数据类型和函数、类等。例如: #基本数据类型 >>> type(123) >>> type('str') >>> type(None) #函数和类 >>> type(abs) >>> type(a) 类型比较 可以在if语句中比较两个对象的数据类型是否一致。 >>> type(123)==type(456) True >>> type(123)==int True >>> type('abc')==type('123') True >>> type('abc')==str True >>> type('abc')==type(123) False type()中常量 types模块中定义的常量可以用于判断对象是否是函数、生成器等类型。 >>> import types >>> def fn(): ... pass ... >>> type(fn)==types.FunctionType True >>> type(abs)==types.BuiltinFunctionType True >>> type(lambda x: x)==types.LambdaType True >>> type((x for x in range(10)))==types.GeneratorType True 4.2 isinstance() 继承关系判断 使用isinstance()函数可以判断一个对象是否是该类型本身或者位于该类型的父继承链上。例如: #继承关系如下 object -> Animal -> Dog -> Husky #创建实例 >>> a = Animal() >>> d = Dog() >>> h = Husky() #继承关系判断 >>> isinstance(h, Husky) True >>> isinstance(h, Dog) True >>> isinstance(h, Animal) True 以上的继承关系中,子类的类型除了本身的类型外,还可以归属于其祖类(父类及以上)的类型。 基本数据类型的判断 isinstance()也可以用来判断基本数据类型。 #判断基本数据类型 >>> isinstance('a', str) True >>> isinstance(123, int) True >>> isinstance(b'a', bytes) True #判断某类型中的一种 >>> isinstance([1, 2, 3], (list, tuple)) True >>> isinstance((1, 2, 3), (list, tuple)) True 优先使用isinstance()判断类型 4.3 dir() dir()函数可以获取一个对象的所有属性和方法,返回一个包含字符串的list。例如: >>> dir('ABC') ['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill'] dir()可以结合getattr()、setattr()以及hasattr()使用,例如: >>> class MyObject(object): ... def __init__(self): ... self.x = 9 ... def power(self): ... return self.x * self.x ... >>> obj = MyObject() >>> hasattr(obj, 'x') # 有属性'x'吗? True >>> obj.x 9 >>> hasattr(obj, 'y') # 有属性'y'吗? False >>> setattr(obj, 'y', 19) # 设置一个属性'y' >>> hasattr(obj, 'y') # 有属性'y'吗? True >>> getattr(obj, 'y') # 获取属性'y' 19 >>> obj.y # 获取属性'y' 19 此类函数是在未知对象内部数据时使用,例如从文件流中读取图像,先判断是否有read()方法,如果有则可以读取。 def readImage(fp): if hasattr(fp, 'read'): return readData(fp) return None 参考: https://www.liaoxuefeng.com/wiki/1016959663602400/1017499532944768 Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-07-03 21:14:35 "},"package/package-module.html":{"url":"package/package-module.html","title":"包与模块","keywords":"","body":"1. Module Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。 例如: support.py表示一个模块,模块名为文件名即support。 def print_func( par ): print \"Hello : \", par return 调用示例: #!/usr/bin/python # -*- coding: UTF-8 -*- # 导入模块 import support # 调用模块里包含的函数 support.print_func(\"Runoob\") 2. Package 包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。 __init__.py 用于标识当前文件夹是一个包,可以为空。 即关系范围如下: 一个包中可以包含多个模块(Python文件),一个模块(Python文件)可以包含多个独立功能的函数。 package > module > function 3. 引用 可以通过as来给模块设定别名缩写,方便引用。 3.1. import # import 模块 import module1[, module2[,... moduleN]] # import 模块中的函数 import module.function # 等价于 from module import function 3.2. from…import # 格式 from modname import name1[, name2[, ... nameN]] # import 模块中函数 from module import function # import 包中的模块 from package import module as alias 3.3. from…import* 把一个模块的所有内容全都导入到当前的命名空间。 from module import * 4. 命名空间与作用域 变量:表示对象的名字或标识 命名空间:表示变量和对象的范围 局部变量和全局变量重名,局部变量会覆盖全局变量。全局变量用global表示。 5. 搜索路径 Python解析器对模块位置的搜索顺序: 当前目录。 PYTHONPATH的每个目录。 查看Python安装时的默认包路径。例如:/usr/lib64/python2.6/site-packages。 可以通过查询sys.path查看模块搜索路径。 5.1. PYTHONPATH 环境变量PYTHONPATH有多个目录组成,类似环境变量PATH。 例如 export PYTHONPATH=/usr/local/lib/python 6. 跨包引用 将项目的根目录加到PYTHONPATH变量中 sys.path.append(\"..\") 示例: project ├── package1 │ ├── __init__.py │ ├── module_11.py │ └── module_12.py ├── package2 │ ├── __init_.py │ ├── module_21.py │ └── module_22.py ├── main.py └── tool.py 6.1. 导入同级模块 module_11.py文件导入module_12.py模块 import module_12 6.2. 导入下级模块 main.py文件导入module_12.py模块 from package1 import module_12 # 或者 import package1.module_12 6.3. 导入上级模块 module_11.py导入上级目录的tool.py模块 import sys sys.path.append(\"..\") import tool 相当于通过sys.path.append(\"..\")进入上级目录,然后类似导入同级目录模块的方式导入。 6.4. 导入跨包下级模块 module_11.py导入package2包的module_21.py模块 import sys sys.path.append(\"..\") from package2 import module_21 相当于通过sys.path.append(\"..\")进入上级目录,然后类似导入下级目录模块的方式导入。 参考: https://www.runoob.com/python/python-modules.html https://packaging.python.org/tutorials/packaging-projects/ https://docs.python.org/3/ Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-11-22 19:27:12 "},"django/install-django.html":{"url":"django/install-django.html","title":"安装Django","keywords":"","body":" 以下使用pip方式安装 1. 安装Python 2. 安装pip 说明:安装完python3默认安装了pip3。 3. 安装虚拟环境 3.1. virtualenv 参考:https://virtualenv.pypa.io/en/latest/installation/ virtualenv可以提供分离的Python环境。 1、安装virtualenv # virtualenv pip install --user virtualenv 2、创建并激活虚拟环境 # 创建虚拟环境路径 mkdir ~/.virtualenvs/ python3 -m venv ~/.virtualenvs/djangodev # 激活虚拟环境 source ~/.virtualenvs/djangodev/bin/activate # 或者 . ~/.virtualenvs/djangodev/bin/activate 3.2. virtualenvwrapper 参考:https://virtualenvwrapper.readthedocs.io/en/latest/install.html 1、安装virtualenvwrapper # virtualenvwrapper pip install --user virtualenvwrapper 将以下内容添加到.zshrc或.bashrc中,然后执行source ~/.zshrc。 export WORKON_HOME=$HOME/.virtualenvs export PROJECT_HOME=$HOME/Devel source /usr/local/bin/virtualenvwrapper.sh 如果出现/usr/local/bin/virtualenvwrapper.sh文件找不到的报错,则在以下目录下查找并将该文件拷贝到/usr/local/bin/目录中。 # ll ~/Library/Python/3.7/bin total 120 -rwxr-xr-x 1 user group 261B 9 21 23:56 pbr -rwxr-xr-x 1 user group 259B 9 21 23:56 virtualenv -rwxr-xr-x 1 user group 264B 9 21 23:56 virtualenv-clone -rwxr-xr-x 1 user group 41K 2 10 2019 virtualenvwrapper.sh -rwxr-xr-x 1 user group 2.2K 2 10 2019 virtualenvwrapper_lazy.sh 2、创建虚拟环境 ➜ ~ mkvirtualenv django Using base prefix '/Library/Frameworks/Python.framework/Versions/3.7' New python executable in /Users/user/.virtualenvs/django/bin/python3.7 Also creating executable in /Users/user/.virtualenvs/django/bin/python Installing setuptools, pip, wheel... done. virtualenvwrapper.user_scripts creating /Users/user/.virtualenvs/django/bin/predeactivate virtualenvwrapper.user_scripts creating /Users/user/.virtualenvs/django/bin/postdeactivate virtualenvwrapper.user_scripts creating /Users/user/.virtualenvs/django/bin/preactivate virtualenvwrapper.user_scripts creating /Users/user/.virtualenvs/django/bin/postactivate virtualenvwrapper.user_scripts creating /Users/user/.virtualenvs/django/bin/get_env_details (django) ➜ ~ workon可以查看当前的虚拟环境。 4. 安装Django pip install Django 5. 验证 如果可以正常显示出以下内容,说明安装django成功。 ~ python Python 3.7.4 (v3.7.4:e09359112e, Jul 8 2019, 14:36:03) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type \"help\", \"copyright\", \"credits\" or \"license\" for more information. >>> import django >>> print(django.get_version()) 2.2.5 >>> 参考 https://docs.djangoproject.com/en/2.2/intro/install/ https://docs.djangoproject.com/en/2.2/topics/install/#installing-official-release Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-09-22 00:53:36 "},"django/quick-start.html":{"url":"django/quick-start.html","title":"创建项目","keywords":"","body":"1. 创建项目 $ django-admin startproject mysite mysite的目录结构 $ tree ./ ./ ├── manage.py # 管理 Django 项目的命令行工具 └── mysite # 项目 ├── __init__.py # 表示一个Python包 ├── settings.py # 项目配置文件 ├── urls.py # url声明 └── wsgi.py 目录说明: 最外层的 mysite/ 根目录是项目的容器。 manage.py: 管理 Django 项目的命令行工具。具体参考django-admin and manage.py。 里面一层的 mysite/ 目录包含你的项目,是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如 mysite.urls). mysite/__init__.py:一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。 mysite/settings.py:Django 项目的配置文件。具体参考 Django settings 。 mysite/urls.py:Django 项目的 URL 声明,就像你网站的“目录”。具体参考 URL dispatcher。 mysite/wsgi.py:项目运行在 WSGI 兼容的Web服务器上的入口。具体参考 How to deploy with WSGI 。 2. 运行 执行以下命令 $ python manage.py runserver 运行结果如下: $ python manage.py runserver Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions. Run 'python manage.py migrate' to apply them. September 22, 2019 - 02:08:02 Django version 2.2.5, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. # 以下是网页访问的日志 [22/Sep/2019 02:08:18] \"GET / HTTP/1.1\" 200 16348 [22/Sep/2019 02:08:18] \"GET /static/admin/css/fonts.css HTTP/1.1\" 200 423 [22/Sep/2019 02:08:18] \"GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1\" 200 86184 [22/Sep/2019 02:08:18] \"GET /static/admin/fonts/Roboto-Regular-webfont.woff HTTP/1.1\" 200 85876 [22/Sep/2019 02:08:18] \"GET /static/admin/fonts/Roboto-Light-webfont.woff HTTP/1.1\" 200 85692 Not Found: /favicon.ico [22/Sep/2019 02:08:19] \"GET /favicon.ico HTTP/1.1\" 404 1972 在浏览器访问http://127.0.0.1:8000/。 3. django-admin django-admin是Django的命令行工具,具体使用帮助如下: $ django-admin Type 'django-admin help ' for help on a specific subcommand. Available subcommands: [django] check compilemessages createcachetable dbshell diffsettings dumpdata flush inspectdb loaddata makemessages makemigrations migrate runserver sendtestemail shell showmigrations sqlflush sqlmigrate sqlsequencereset squashmigrations startapp startproject test testserver 4. manage.py $ python manage.py --help Type 'manage.py help ' for help on a specific subcommand. Available subcommands: [auth] changepassword createsuperuser [contenttypes] remove_stale_contenttypes [django] check compilemessages createcachetable dbshell diffsettings dumpdata flush inspectdb loaddata makemessages makemigrations migrate sendtestemail shell showmigrations sqlflush sqlmigrate sqlsequencereset squashmigrations startapp startproject test testserver [sessions] clearsessions [staticfiles] collectstatic findstatic runserver 参考 https://docs.djangoproject.com/en/2.2/intro/tutorial01/ https://docs.djangoproject.com/en/2.2/ref/django-admin/ Copyright © www.huweihuang.com 2017-2018 all right reserved,powered by GitbookUpdated at 2019-09-22 17:51:41 "}}