笔记目录

  • 9月22日:《基础教程》基础知识
    • ·模块导入
    • ·用变量引用函数(或者Python中大多数的对象)
    • ·将数值转换成字符串的方法:str类型、repr函数
  • 9月23日:列表、元组
    • ·序列索引可以为负数:
    • ·序列的分片和步长
    • ·序列相加,乘法;列表和字符串不能相加
    • ·in运算符 测试成员资格
  • 9月24日:序列分片,列表方法,字符串格式化
    • ·list函数:将 所有类型的序列 转换成 列表
    • ·删除列表元素 del
    • ·分片赋值 name[a:b]
    • ·列表方法
      • ·列表方法作用和返回值 表格
      • ·高级排序,sort方法的使用
    • ·元组:不可变序列
    • ·字符串格式化 %
    • ·字符串格式化转换说明符
    • ·字符串 常用方法
  • 9月25日:字典方法,python基本语句
    • ·字典基本操作
    • ·字典的格式化字符串
    • ·字典方法
    • ·python基本语句
      • ·赋值语句
      • ·条件语句
      • ·循环语句
      • ·列表推导式——轻量级循环
      • ·其他语句:pass、del、exec和eval
  • 9月26日:
    • ·直接赋值,浅拷贝copy、深拷贝deepcopy
    • ·函数
      • ·文档化函数
      • ·位置参数、关键词参数、提供默认值
      • ·收集参数:定义函数时允许使用不定数目的参数
      • ·收集参数逆过程:调用函数时“分割”字典或者序列
      • ·全局变量与局部变量
  • 9月28日:抽象、异常
    • ·多态、封装、继承
    • ·类和类型
      • ·特性、函数和方法
      • ·私有
      • ·类的命名空间
      • ·超类、检查继承,多类继承
    • ·异常
  • 10月5日:
    • ·魔法方法、属性和迭代器
      • ·新式类
      • ·构造方法
      • ·魔法方法创建序列和映射、子类化列表字典字符串
      • ·属性
      • ·迭代器
      • ·生成器
      • ·八皇后问题
  • 附录A:到时待办
  • 附录B:资料

9月22日:《基础教程》基础知识

第1章 快速改造:基础知识

  • 长整数,python2和python3有关长整数的区别?

python2中有long类型
python3中没有long类型,只有int类型

>>> 1000000000000000000    #教材
1000000000000000000L
>>> 1000000000000000000L
1000000000000000000L
>>> 1000000000000000000    #测试
1000000000000000000
>>> 1000000000000000000L
SyntaxError: invalid syntax
  • 十六进制和八进制
>>> 0xAF    #十六进制数前面是0x
175
>>> 010    #八进制数前面是0
8

·模块导入

  • 除非真的需要from这个形式的模块导入语句,否则应该坚持使用普通的import。
>>> import math    #正常导入模块,使用导入模块中的函数
>>> math.floor(32.9)
32
--------------------
>>> from math import sqrt    #使用from可以直接使用函数不用加模块,但是会有不同模块重名函数的现象需要注意
>>> sqrt(9)
3.0

·用变量引用函数(或者Python中大多数的对象)

>>> foo=math.sqrt
>>> foo(4)
2.0

·将数值转换成字符串的方法:str类型、repr函数

  • 将数值转换成字符串的方法:str类型、repr函数和 反引号(反引号在python 3中已经不再使用)
>>> temp=23
>>> print("The temperature is "+ repr(temp))
The temperature is 23

9月23日:列表、元组

第2章 列表和元组
2.1序列概览

  • 序列(内建序列):列表、元组、字符串、buffer对象、xrange对象

·序列索引可以为负数:

索引范围为[ (-n) ~ (n-1) ]

sequence = [1,2,3,4,5]
print("sequence[4] = " + str(sequence[4]))
print("sequence[-5] = " + str(sequence[-5]))sequence[4] = 5
sequence[-5] = 1

·序列的分片和步长

  • 冒号“:”实现分片 和 步长,步长隐式设置为1
  • 形式为:number[ a : b [ : c ] ]
  • c不能为0,默认为;a为分片的首个元素索引,b为分片最后一个元素的下一个元素索引,也就是a在分片中,b不在分片中
  • 从首个元素开始取时可以空置a,取到最后一个元素时可以空置b
  • 如果c是正数(比如隐式设置),那么number[a]必须在number[b]左边;如果c是负数,那么number[a]必须在number[b]右边。
number = [1,2,3,4,5,6,7,8,9,10]
print("number[2:10] = " + str(number[2:10]))            #冒号“:”实现分片,步长隐式设置为1
print("number[2:10:2] = " + str(number[2:10:2]))        #冒号“:”实现分片 和 步长,步长隐设置为2
print("number[:8] = " + str(number[:8]))                #从首个元素开始,a为0,也可以空置
print("number[2:] = " + str(number[2:]))                #d到最后一个元素结束,b为n,也可以空置
print("number[10:0:-2] = " + str(number[10:0:-2]))      #步长为负数,a索引元素必须在b索引元素右边
print("number[::2] = " + str(number[::2]))              #a,b都空置
print("number[::] = " + str(number[::]))                #a,b,c都空置number[2:10] = [3, 4, 5, 6, 7, 8, 9, 10]
number[2:10:2] = [3, 5, 7, 9]
number[:8] = [1, 2, 3, 4, 5, 6, 7, 8]
number[2:] = [3, 4, 5, 6, 7, 8, 9, 10]
number[10:0:-2] = [10, 8, 6, 4, 2]
number[::2] = [1, 3, 5, 7, 9]
number[::] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

·序列相加,乘法;列表和字符串不能相加

number1 = [1,2,3]
number2 = [4,5,6]
string1 = "Hello,"
string2 = "World!"
print("number1 + number2 =" + str(number1 + number2)) #列表相加
print("string1 + string2 =" + string1 + string2)
#print("number1 + string1 =" + str(number1 + string1))
#这句报错,列表和字符串不能相加
print("number1 * 3 = " + str(number1 * 3))              #列表相乘number1 + number2 =[1, 2, 3, 4, 5, 6]
string1 + string2 =Hello,World!
number1 * 3 = [1, 2, 3, 1, 2, 3, 1, 2, 3]

·in运算符 测试成员资格

subject = "$$$ Get rich now!!! $$$"
if "$$$" in subject : print("'$$$' in subject\n")'$$$' in subject

9月24日:序列分片,列表方法,字符串格式化

2.3 列表:Python的苦力

·list函数:将 所有类型的序列 转换成 列表

  • 字符串不能修改,可以用list函数转化成列表
temp = list("Hello!")
print(temp)['H', 'e', 'l', 'l', 'o', '!']

·删除列表元素 del

  • 使用del语句实现,也可以删除分片
names = ['Alice','Beth','Cecil','Dee-Dee','Earl']
print(names)
del names[2]
print(names)
del names[1:3]
print(names)['Alice', 'Beth', 'Cecil', 'Dee-Dee', 'Earl']
['Alice', 'Beth', 'Dee-Dee', 'Earl']
['Alice', 'Earl']

·分片赋值 name[a:b]

  • 可以通过 分片 进行多个元素赋值;
  • 也可以与原序列不等长的赋值;
  • 还可以通过 分片赋值 插入或者删除元素;
name = list('Perl')
name[2:] = list('ar')        #通过分片进行多个元素赋值
print(name)
name[1:] = list('ython') #与原序列不等长的赋值
print(name)
name[1:1] = list('&&&&&&&')  #通过 分片赋值 插入新的元素
print(name)
name[1:12] = []                #通过 分片赋值 删除元素
print(name)['P', 'e', 'a', 'r']
['P', 'y', 't', 'h', 'o', 'n']
['P', '&', '&', '&', '&', '&', '&', '&', 'y', 't', 'h', 'o', 'n']
['P', 'n']

·列表方法

  • 列表方法:append,count,extend,index,insert,pop,remove,reverse,sort

·列表方法作用和返回值 表格

列表方法 作用 返回值 相关内容
append 列表末尾追加元素 None
count 元素出现次数 次数
extend 列表末尾扩展另一个序列 None 末尾分片赋值
index 第一个匹配值的索引 索引
insert 列表插入元素 None 分片赋值
pop 移除最后一个元素 元素 insert(0,…),pop(0),
append(),pop()
remove 移除匹配项的第一个元素 None
reverse 列表反向 None reversed ( ) 函数返回迭代器
可以使用 y = list(reversed(x))
sort 列表排序 None sorted ( ) 函数返回列表
可以使用 y = sorted(x)

·高级排序,sort方法的使用

  • number.sort(cmp,key=None,reverse=False)
  • sort方法三个参数,第一个cmp函数;
  • 第二个key关键字参数,排序过程中使用的函数,如len;
  • 第三个reverse,布尔值,默认设置为False不反向;
  • 以上三个参数适用于sorted()函数;

·元组:不可变序列

  • 一个元素的元组,必须加逗号,否则即使加圆括号也不行;
print(3*(42))
print(3*(42,))126
(42, 42, 42)
  • tuple函数,把一个序列转换为元组;
    类似于list函数,把一个序列转换为列表;

  • 元组意义:

1、元组可以作为映射的键使用;
2、元组一般作为内建函数和方法的返回值;

第3章 使用字符串

·字符串格式化 %

  • 下面例子中values如果是序列,会被解释成一个值;
  • 如果本身就有%,那么必须使用%%,%才不会被认为是 转换说明符;
string1 = "Hello,%s! %s enough fo ya?"
values = ("world","Hot")   #values如果是序列,会被解释成一个值
print(string1 %values)Hello,world! Hot enough fo ya?#对比
string1 = "Hello,%s! enough fo ya?"
values = ["world","Hot"]   #values如果是序列,会被解释成一个值
print(string1 %values)Hello,['world', 'Hot']! enough fo ya?
string1 = "Pi with three decimals: %.3f."
from math import pi
print(string1 % pi)Pi with three decimals: 3.142.

·字符串格式化转换说明符

  • 注意 顺序
内容 说明
1 %字符 标记转换说明符的开始
2 转换标志
(可选)
- 表示左对齐;
+ 表示在转换值之前要加上正负号;
“ ”(空白字符)表示正数之前保留空格;
0 表示转换值若位数不够则用0填充
3 最小字段宽度
(可选)
转换后的字符串至少应该具有该值指定的宽度。
如果是 * ,则宽度会从值元组中读出
4 点( . )后跟精度值
(可选)
如果转换的是实数,精度值就表示出现在小数点后的位数。
如果转换的是字符串,那么该数字就表示 最大字段宽度。
如果是 * ,那么精度将会从元组中读出。
5 转换类型 下表
转换类型 含义
d,i 带符号的十进制整数
o 不带符号的八进制
u 不带符号的十进制
x 不带符号的十六进制(小写)
X 不带符号的十六进制(大写)
e 科学计数法表示的浮点数(小写)
E 科学计数法表示的浮点数(大写)
f,F 十进制浮点数
g 如果指数大于-4或者小于精度值则和e相同,其他情况与f相同
G 如果指数大于-4或者小于精度值则和E相同,其他情况与F相同
C 单字符(接受整数 或者 单字符字符串)
r 字符串(使用 repr 转换任意Python对象)
s 字符串(使用 str 转换任意Python对象)
from math import pi
print("%10f" % pi)                    #字段宽度 10
print("%10.2f" % pi)              #字段宽度 10,精度 2
print("%*.*s" % (10,5,"abcdefgh"))  #使用 * 作为字段宽度或者精度(或者两者都使用*),数值会从元组参数中读出3.1415933.14abcde
from math import pi
print("%010.2f" % pi)                 #字段宽度 10,精度 2,位数不够用 0 填充
print("%-10.2f" % pi + "abcd")             #字段宽度 10,精度 2,- 表示左对齐数值,打印出来的数字右侧有额外的空格
print("% 5d" % 10 + "\n" + "% 5d" % -10)    #" "意味着在正数前面加上空格,
print("%+5d" % 10 + "\n" + "%+5d" % -10)  # + 表示不管是正数负数都标示出符号0000003.14
3.14      abcd10-10+10-10

·字符串 常用方法

string1.find(string2[,a[,b]]) 字符串string1起始a和终止b范围内查找字符串string2,并返回最左端索引值,没找到返回-1,
可以不提供a,b;也可以只提供 a 起始
string1.join(string2) 返回用string1连接string2中元素的字符串
string1.split([separate[,maxsplit]]) 返回字符串string1中用字符串separate分隔所得的所有 单词的列表,maxsplit指定最多切割几次;
separate默认设置空格“ ”,maxsplit默认设置无穷大
string.lower() 返回字符串string的小写字母版本
string1.replace(old,new[,max]] 返回字符串string1的副本,用new字符串替换old字符串,最多替换max次
string1.strip([chars]) 返回字符串string1的副本,其中string1开头和结尾所有的位于字符列表[chars]中的字符都被去除;
[chars]隐形设置为所有的空白字符,如空格、tab和换行符
string.translate(table[,deletechars]) 返回字符串的副本,其中所以字符都是用table进行了转换,可选择删除出现在deletechars中的所有字符;
table由string模块中的maketrans函数构造
table = str.maketrans("cs","kz")        #注意python 3 中maketrans的使用方式
string1 = "this is an incredible test"
string2 = string1.translate(table)
print(string1 + '\n' + string2 + '\n')this is an incredible test
thiz iz an inkredible tezt

9月25日:字典方法,python基本语句

·字典基本操作

  • dict函数建立字典,类似list、tuple、str一样;
    dict可以通过其他字典 或者 (键-值)对的序列建立字典;
    也可以通过关键字参数创建字典;
  • 字典 是唯一内建的映射类型;
  • len(d);del d[k];k in d;等操作都可用,只不过k in d 查找的是键的成员资格,而不是值得成员资格;
items = [('name','Gumby'),('age',42)]
d = dict(items)                            #通过其他字典 或者 (键-值)对的序列建立字典;
print(d)
d2 = dict(number = 54,name = 'Richard')    #通过关键字参数创建字典;
print(d2){'name': 'Gumby', 'age': 42}
{'number': 54, 'name': 'Richard'}

·字典的格式化字符串

  • 字典除了可以元组一样使用字符串格式化功能,还可以在每个转换说明符中的 % 字符后面,加上(键),后面再跟其他元素说明;
items = [('name','Gumby'),('age',42)]
d = dict(items)                            #通过其他字典 或者 (键-值)对的序列建立字典;
print("%(name)s's age is %(age)d!" %d)   #在每个转换说明符中的 % 字符后面,加上(键),后面再跟其他元素说明Gumby's age is 42!

·字典方法

字典方法 作用 返回值 相关
d.clear() 清除字典中所有的项 None
d.copy() 浅复制一个拥有相同键-值对的新字典,一般用deepcopy函数进行深复制 dict deepcopy(dict)
dict.fromkeys(sequence[,value]) 返回从sequence中获得的键和被设置为value的值(value的默认设置值None)的字典。可以直接在字典类型dict上作为类方法调用 dict
d.get(key[,default]) 如果d[key]存在,那么将其返回;否则返回给定的默认值default(default不设置默认None) d[key]或default
d.items() 返回字典d中(键,值)对的列表 list
d.iteritems() 和d.items()相同,只不过返回的是迭代器,是列表中的一个可迭代对象 iterator
d.keys() 返回字典d的键的列表 list
d.iterkeys() 和d.keys()相同,只不过返回的是迭代器,是列表中的一个可迭代对象 iterator
d.values() 返回字典d的值得列表 list
d.itervalues() 和d.values()相同,只不过返回的是迭代器,是列表中的一个可迭代对象 iterator
d.pop(key[,default]) 移除,并且返回d[key],如果d[key]不存在则返回default
d.popitem() 移除,并返回字典d中任意一个(键-值)对 tuple(键,值)
d.setdefault(key[,default]) 返回d[key];d[key]不存在返回给定的默认值default(默认为None)并将d[key]的值绑定给default d[key]或default
d.update(other) other如果是字典,会将other每一项都加入d中(可能会改写已存在项);other也可以是(键-值)对的序列或关键字参数,update方法和dict函数一样使用 None

·python基本语句

  • print语句用(,)逗号间隔参数,打印的结果每个逗号都有一个空格;
  • import语句可以加as用于别名,也可以结合 from * import * as *;

·赋值语句

  • 序列解包:
    -多个赋值操作可以同时进行,也可以交换多个变量,还可以结合(*)星号运算符;
x,y,z = 1,2,3               #多个赋值操作可以同时进行
print(x,y,z)
x,y = y,x                  #也可以交换多个变量
print(x,y,z)
x,y,*rest,z = 1,2,3,4,5        #还可以结合(*)星号运算符
print(x,y,rest,z)1 2 3
2 1 3
1 2 [3, 4] 5
  • 链式赋值:x = y = somefunction()
  • 增量赋值:+=;-=;*=;/=;%=;

·条件语句

  • 布尔值为假:False,0;None,(),"";[];{};
  • if / elif / else
  • 比较运算符 连接使用 :0 < age < 100;
  • is:同一性运算符:判定 同一性 而不是 相等性;
  • and、or、not:布尔运算符
  • a if b else c
print("abc" if True else "ABC")              # a if b else c
print("abc" if False else "ABC")abc
ABC
  • 断言:assert
age = -1
assert 0<age<100 "The age must be realistic!"
print(age)assert 0<age<100 "The age must be realistic!"                     ^
SyntaxError: invalid syntax

·循环语句

  • range()函数 和 xrange()函数:内建的范围函数
    ·range()函数以此创建整个序列,而xrange()函数一次只创建一个数,效率更高
    ·注意:python3 中取消了 range 函数,而把 xrange 函数重命名为 range,所以现在直接用 range 函数即可
for number in range(1,101,20):       #range([start,] end [,step])print(number)1
21
41
61
81
  • 并行迭代:zip()函数
    ·zip()函数:可以把两个序列“压缩”在一起,然后返回一个元组的列表;
    ·zip可以处理不等长的序列,当最短的序列“用完”为止;
names = ['anne','beth','george','damon']
ages = [12,45,109]
for name,age in zip(names,ages):            #把两个序列“压缩”在一起,然后返回一个元组的列表print(name,'is',age,'years old')        #names有四个元素,ages有三个元素,zip可以处理不等长的序列,当最短的序列“用完”为止;anne is 12 years old
beth is 45 years old
george is 109 years old
  • 内建的enumerate()函数:可以在提供索引的地方迭代 索引-值 对;
names = ['anne','beth','george','damon']
for index,name in enumerate(names):         print(index,name)       0 anne
1 beth
2 george
3 damon
  • while True / break习语

·while True实现一个永远不会停止的循环,但是在循环内部的if语句用break语句跳出

while True:word = input("Please enter a word:")if not word:breakprint ('The word was ' + word)Please enter a word:Richard
The word was Richard

·列表推导式——轻量级循环

abc = [x*x for x in range(10)]                      #列表推导式:工作方式类似于for循环
print(abc)
abc = [x*x for x in range(10) if x%3==0]         #可以通过增加一个if部分添加到列表推导式中
print(abc)
abc = [(x,y) for x in range(3) for y in range(3)]  #也可以增加更多for语句的部分
print(abc)
abc = [(x,y) for x in range(3) for y in range(3) if x<y]
print(abc)[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 9, 36, 81]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
[(0, 1), (0, 2), (1, 2)]

·其他语句:pass、del、exec和eval

  • pass语句:python中控代码块是非法的,解决方法就是在语句块中加上一个pass语句;
names = ['Richard','Tom','Jerry']
for name in names:if name == 'Richard':print('Welcome!')elif name == 'Tom':pass                       #不允许有空代码块elif name == 'Jerry':print('Access Denied!')Welcome!
Access Denied!
  • del语句:不仅会移除一个对象的引用,也会移除那个名字本身;
  • exec执行字符串;eval求值字符串;命名空间:in scope;

9月26日:

·直接赋值,浅拷贝copy、深拷贝deepcopy

  • 直接赋值:传递对象的引用而已,原始列表改变,被赋值的也会做相同的改变
    ·列表list、字典dict都是如此;
    ·对象拷贝的是引用
xo=[1,2,3,4,5]
yo=xo          #列表list直接赋值
yo[1]=200
print(xo)
print(yo)[1, 200, 3, 4, 5]
[1, 200, 3, 4, 5]
  • 浅拷贝copy:没有拷贝子对象,所以原始数据改变,子对象会改变
    ·对象拷贝的是数据
    ·子对象拷贝的是引用
import copy
xo=[1,2,3,[4,5,'a'],6]
yo=copy.copy(xo)       #浅拷贝
yo.append(7)            #结果原始对象没有改变,因为原始对象拷贝的是原始数据
print(xo)
print(yo)
xo=[1,2,3,[4,5,'a'],6]
yo=copy.copy(xo)       #浅拷贝
yo[3].append('b')     #结果子对象改变了,因为子对象拷贝的是引用
print(xo)
print(yo)[1, 2, 3, [4, 5, 'a'], 6]            #结果原始对象没有改变,因为原始对象拷贝的是原始数据
[1, 2, 3, [4, 5, 'a'], 6, 7]
[1, 2, 3, [4, 5, 'a', 'b'], 6]      #结果子对象改变了,因为子对象拷贝的是引用
[1, 2, 3, [4, 5, 'a', 'b'], 6]
  • 深拷贝deepcopy:包含对象里面的子对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变
    ·对象拷贝的是数据
    ·子对象拷贝也是数据
import copy
xo=[1,2,3,[4,5,'a'],6]
yo=copy.deepcopy(xo)       #深拷贝
yo.append(7)                #结果原始对象没有改变,因为原始对象拷贝的是原始数据
print(xo)
print(yo)
xo=[1,2,3,[4,5,'a'],6]
yo=copy.deepcopy(xo)       #深拷贝
yo[3].append('b')         #结果子对象也没有改变,因为子对象拷贝的是也是原始数据
print(xo)
print(yo)[1, 2, 3, [4, 5, 'a'], 6]            #结果原始对象没有改变,因为原始对象拷贝的是原始数据
[1, 2, 3, [4, 5, 'a'], 6, 7]
[1, 2, 3, [4, 5, 'a', 'b'], 6]      #结果子对象也没有改变,因为子对象拷贝的是也是原始数据
[1, 2, 3, [4, 5, 'a', 'b'], 6]

·函数

  • 使用 def 语句创建函数

·文档化函数

  • 可以加入注释(#开头)
  • 在 def 语句后面,函数的开头写下字符串,他就会作为函数的一部分进行存储,成为 文档字符串
  • 可以用 hanshuming.__doc__进行访问(注意这里前后都是双下划綫)
def square(x):'Calculates the square of the number x.'return x*x
print(square.__doc__)Calculates the square of the number x.

·位置参数、关键词参数、提供默认值

  • 位置参数:用 参数的顺序 作为区分参数的依据
  • 关键词参数:指定 每个关键词 的参数,关键词要相同,顺序可以不同
  • 提供默认值:函数定义的时候,直接将关键词赋值,这样调用函数的时候可以不提供这些参数的值,而是用定义时候的默认值
def hello_1(greeting,name):                                      #位置参数,按照参数顺序进行传参print('%s,%s!' %(greeting,name))
hello_1('Hello','world')hello_1(name = 'all the people',greeting = 'Nice to meet you')    #关键词参数,按照关键词进行传参,无关顺序def hello_2(greeting = 'Hello',name = 'World'):                    #greeting参数没有提供,使用了默认值,name没有print('%s,%s!' %(greeting,name))
hello_2(name = 'Richard')Hello,world!
Nice to meet you,all the people!
Hello,Richard!

·收集参数:定义函数时允许使用不定数目的参数

  • 用星号(*)将剩下的 位置参数 收集到一个元组中
  • 用双星号(**)将剩下的 关键字参数 收集到一个字典中
def print_param(x,y,z=3,*pospar,**keypar):
# x,y,z三个参数有默认值
# *pospar将剩下的 位置参数 收集到一个元组中
# **keypar将剩下的 关键字参数 收集到一个字典中print(x,y,z)print(pospar)print(keypar)
print_param(1,2,3,4,5,6,7,foo=1,bar=2)1 2 3
(4, 5, 6, 7)
{'foo': 1, 'bar': 2}

·收集参数逆过程:调用函数时“分割”字典或者序列

  • 用星号(*)在调用函数时“分割”序列
  • 用双星号(*)在调用函数时“分割”字典
def add(x,y):print('x + y = ' + str(x+y))
params = (1,2)
add(*params)                                        #用星号(*)在调用函数时“分割”序列def hello(greeting,name):print('%s,%s!' %(greeting,name))
params2 = {'greeting': 'Hello', 'name': 'world'}
hello(**params2)                                    #用双星号(*)在调用函数时“分割”字典x + y = 3
Hello,world!

·全局变量与局部变量

  • 在子函数中,使用globals()[“ 全局变量名 ”]使用全局变量
  • locals()函数和globals()函数使用相同,会返回局部变量值

  • 在子函数中,想要声明全局变量,可以使用 global 关键词
  • 在子函数中,想要声明外部作用域变量,如上一层函数的局部变量,可以使用 nonlocal 关键词

9月28日:抽象、异常

·多态、封装、继承

多态:可以对不同类的对象使用同样的操作;不需要检测类型
封装:对外部世界隐藏对象的工作细节;
继承:以通用的类为基础建立专门的类对象;

  • 唯一能毁掉多态的是,使用函数显式的检查类型,比如type、isinstance、issubclass等,要避免使用这些;
  • 方法(method)和特性(attribute)是构成对象(object)的一部分;

·类和类型

  • 旧版本中,类和类型区别明显,内建的对象基于类型,自定义的对象基于类,可以创建类不能创建类型;新版本中可以创建内建类型的子类型,类和类型区别不大;
  • 描述对象的类:习惯使用单数名词,首字母大写,如Bird、Lark;
  • 定义子类只是个定义更多(或者是重载已经存在的)的方法的过程;

·特性、函数和方法

  • self参数:定义方法时对于对象自身的引用;
  • 可以将特性绑定到一个普通函数上,也可以使用其他变量引用同一个方法:
class Bird:song = 'Squaawk!'def sing(self):print(self.song)def method(self):print('I have a self!')
def function():print('I don\'t ...')instance = Bird()
instance.method()
instance.method = function     #将特性绑定到一个普通函数上
instance.method()bird = Bird()
bird.sing()
birdsong = bird.sing           #使用其他变量引用同一个方法
birdsong()I have a self!
I don't ...
Squaawk!
Squaawk!

·私有

  • python并不直接支持私有方式,为了让方法或者特性变为私有(从外部无法访问),只要在它的名字前面加上 双下划线 。
class Secretive:def __inaccessible(self):print("Bet you can\'t see me...")def accessible(self):print("The secret message is:")self.__inaccessible()
s = Secretive()
s.accessible()                          #没加双下划綫的方法或特性可以被外部访问
try:s.__inaccessible()                      #加双下划线的方法或特性不能被外部访问
except AttributeError as e:print(e)The secret message is:
Bet you can't see me...
'Secretive' object has no attribute '__inaccessible'
  • 类的内部定义中,所有以双下划线开始的名字,都被“翻译”成前面加上单下划线和类名的形式:
print(Secretive._Secretive__inaccessible)<function Secretive.__inaccessible at 0x02E540B8>
  • 所以基于上面的“解释”,还是可以在类外访问这些私有方法,尽管不应该这么做:
s._Secretive__inaccessible()Bet you can't see me...
  • 如果不需要使用这种方法但是又想让其他对象不要访问内部数据,可以使用 单下划线 进行习惯说明;比如所有前面有下划线的名字都不会被带星号的import语句导入from module import *

·类的命名空间

  • 类的定义就是执行代码块,所以定义类时会生成这个类的命名空间,这个命名空间可以由 类内的所有成员 访问;
class C:members = 0def init(self):C.members += 1
x = C()
x.init()
print(C.members)
y = C()
y.init()                #members特性是C类的所有实例共同的,而不是每个实例都有一个
print(C.members)1
2

·超类、检查继承,多类继承

  • 定义类时在括号里指定超类(基类);
  • 使用内建函数issubclass函数检查一个类是不是另一个的子类;
  • 想要知道已知类的基类们,可以直接使用类的特殊特性__bases__;
  • 检查一个对象是否是一个类的实例,可以使用isinstance函数;
  • 想知道一个对象属于哪个类,可以使用__class__特性;
  • 多类继承时,写在前面的先继承的超类会重写后面超类的同名方法;多类继承要避免使用;
  • 查看对象内存储的值,可以使用__dict__特性;
class C:def method(self):print('This is a superclass C!')
class D:def method(self):print('This is a superclass D!')
class SubCD(C,D):members = 0def submethod(self):self.id = 0print('This is a subclass SubCD!')
print(issubclass(D,C),issubclass(SubCD,C))          #使用内建函数issubclass函数检查一个类是不是另一个的子类;
print(SubCD.__bases__)                              #想要知道已知类的基类们,可以直接使用类的特殊特性__bases__;
subcd = SubCD()
print(isinstance(subcd,SubCD),isinstance(subcd,C))  #检查一个对象是否是一个类的实例,可以使用isinstance函数;
print(subcd.__class__)
subcd.submethod()
subcd.method()                  #多类继承,写在前面的先继承的超类会重写后面超类的同名方法,这里method是C的而不是D的
print(subcd.__dict__)                               #查看对象内存储的值False True
(<class '__main__.C'>, <class '__main__.D'>)
True True
<class '__main__.SubCD'>
This is a subclass SubCD!
This is a superclass C!
{'id': 0}

·异常

  • 异常基类:Exception,内建异常都在exceptions模块中;

  • raise可以引发异常,不用参数(except子句内重引发当前捕捉到的异常),也可以 raise IndexError('index out of bounds')

  • except子句:except (ZeroDivisionError,TypeError) as e:注意必须有圆括号

  • try / except / except / else / finally语句:
    except子句,捕捉到异常以后做什么
    else子句,没有捕捉到异常做什么
    finally子句,不管捕捉到还是没捕捉到,做完finally子句中的事再结束,一半用于关闭文件或者网络套接字

  • 栈跟踪:如果异常在函数内引发而没有被捕捉处理,它会“浮”到函数调用的地方,还没有被处理的话则会一直传播到主程序,如果主程序没有异常处理程序,程序会带着 栈跟踪 中止。

10月5日:

·魔法方法、属性和迭代器

·新式类

  • 使用新式方法:__metaclass__ = type
  • 如果没有兼容之前旧版本Python的需要,那么所有的类都写为新式的类,并且使用super函数这样的特性;

·构造方法

  • 自己写构造方法:def __init__(self)
  • 析构方法:__del__(self),因为调用的具体时间是不可知的,所以要尽力避免使用__del__函数;
  • 子类的构造方法必须调用超类的构造方法来确保进行基本的初始化,方法:(1)调用超类构造方法的未绑定版本;(2)使用super函数。
class Bird:def __init__(self):self.hungry = Truedef eat(self):if self.hungry:print("Aaaah...")self.hungry = Falseelse:print("No,Thanks!")
class SongBird(Bird):def __init__(self):Bird.__init__(self)                 #旧版本Python使用的是旧式类,需要调用超类构造方法的未绑定版本super(SongBird,self).__init__()        #新式类 使用super函数self.sound = "Squawk!"def sing(self):print(self.sound)
sb = SongBird()
sb.sing()
sb.eat()
sb.eat()Squawk!
Aaaah...
No,Thanks!

(1)在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(这成为绑定方法)。但如果直接调用类的方法(比如Bird.__init__),那么就没有实例会被绑定,这样就可以自由地提供需要的self参数,这样的方法成为未绑定方法。
(2)当前的类和对象可以作为super函数的参数使用,调用函数返回的对象的任何方法都是调用超类的方法,而不是当前类的方法。super函数会查找所有的超类(以及超类的超类),知道找到所需的特性为止(或者引发一个AttributeError异常)

·魔法方法创建序列和映射、子类化列表字典字符串

·属性

  • 属性
  • property函数创建属性(收藏夹中有@property装饰器的使用)
  • 静态方法和类成员方法(类似property函数和装饰器,静态方法和类成员方法也有函数和装饰器两种实现方法)
  • __getattr__方法和__setattr__方法用于旧式类实现属性
  • 参见收藏夹:[python]:使用描述器的两种用法,装饰器和特殊函数
  • 参见收藏夹:Python 类对象和实例对象访问属性的区别、property属性
# 定义一个类
class A(object):# 类属性,直接在类中定义的属性是类属性#   类属性可以通过类或类的实例访问到count = 0def __init__(self):# 实例属性,通过实例对象添加的属性属于实例属性#   实例属性只能通过实例对象来访问和修改,类对象无法访问修改self.name = '孙悟空'self.count += 1             #这里self.count和A.count是不同的,A.count是类属性,self.count是实例属性# 实例方法#   在类中定义,以self为第一个参数的方法都是实例方法#   实例方法在调用时,Python会将调用对象作为self传入  #   实例方法可以通过实例和类去调用#       当通过实例调用时,会自动将当前调用对象作为self传入#       当通过类调用时,不会自动传递self,此时我们必须手动传递selfdef test(self):print('这是test方法~~~ ' , self)    # 类方法    # 在类内部使用 @classmethod 来修饰的方法属于类方法# 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象#   类方法和实例方法的区别,实例方法的第一个参数是self,而类方法的第一个参数是cls#   类方法可以通过类去调用,也可以通过实例调用,没有区别@classmethoddef test_2(cls):print('这是test_2方法,他是一个类方法~~~ ',cls)print(cls.count)# 静态方法# 在类中使用 @staticmethod 来修饰的方法属于静态方法  # 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用  # 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数# 静态方法一般都是一些工具方法,和当前类无关@staticmethoddef test_3():print('test_3执行了~~~')a = A()
#a.count = 10
#A.count = 100
#print('A ,',A.count)
#print('a ,',a.count)
#print('A ,',A.name)
#print('a ,',a.name)   # a.test() 等价于 A.test(a)# A.test_2() 等价于 a.test_2()A.test_3()
a.test_3()

·迭代器

  • 只要实现了__iter__方法的对象都能进行迭代,不止序列和字典;
  • __iter__方法会返回一个迭代器,所谓的迭代器就是具有next方法。Python 3.0迭代器对象实现__next__方法而不是next方法,新的内建函数next()可以用于访问这个方法,也就是next(it)等同于以前的it.next()
  • 可以用list构造方法显式地将迭代器转化成列表
class TestIterator:                  #TestIterator是一个迭代器value = 0def __next__(self):                #使用next函数会出错误,必须使用__next__函数self.value += 1if self.value > 10:raise StopIterationreturn self.valuedef __iter__(self):return self                    #返回自身ti1 = TestIterator()
for v in ti1:if v>5 :print(v)breakti2 = TestIterator()
li = list(ti2)                     #使用list构造方法显式地将迭代器ti2转化成列表
print(li)[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
6

·生成器

  • 生成器是一种用普通的函数语法定义的迭代器,是一个饱含yield关键字的函数;就算不使用生成器也是也可以的,但是生成器更优雅;
def flatten(nested):             #生成器就是带有关键字yield的函数for sublist in nested:for element in sublist:yield element           #yield关键字
nested = [[1,2],[3,4],[5]]
for num in flatten(nested):print(num)
li = list(flatten(nested))
print(li)1
2
3
4
5
[1, 2, 3, 4, 5]
  • 递归的生成器处理多层嵌套
  • 不能迭代类似于字符串的对象,一是字符串不应该被展开而应该作为一个原子值,二是字符串强行被展开的时候会导致无穷递归,因为一个字符串的第一个元素是另一个长度为1的字符串,而长度为1的字符串的第一个元素就是字符串本身。
  • 检查一个对象是不是类似于字符串最简单、最快速的方法:试着将对象和一个字符串拼接,看会不会出现TypeError。不是用isinstance函数检查类型是不是字符串,而是检查对象的行为是不是像一个字符串。
def flatten(nested):             try:#不要迭代类似于字符串的对象,try:nested + ' 'except TypeError:passelse:raise TypeError          #而是把字符串当成一个整体原子值for sublist in nested:for element in flatten(sublist):      #这利用了递归处理嵌套多层的列表yield elementexcept TypeError:yield nestednested = [[1,2,[3,[4]]],[[5,6],7],[8],'qwe',[9,["asd",10]]]  #有多层嵌套列表,列表中也有字符串,
li = list(flatten(nested))
print(li)[1, 2, 3, 4, 5, 6, 7, 8, 'qwe', 9, 'asd', 10]
  • yield是一个表达式,而不是语句使用,也就是说yield方法返回值,返回的是外部通过send方法发送的值;
  • 生成器在旧版本中没有,可以用列表和append方法进行模拟

·八皇后问题

  • 这里用生成器解决八皇后问题还需要继续理解一下,特别是相比return
def conflict(state,nextX):nextY = len(state)for i in range(nextY):if (state[i]==nextX)or((i-state[i])==(nextY-nextX))or((i+state[i])==(nextY+nextX)):#if abs(state[i]-nextX) in (0,nextY-i):  #两个点的横坐标差 等于 纵坐标差return True return False
def queen(num=4,state=()):for pos in range(num):if not conflict(state,pos):if len(state)==num-1:yield (pos,)else:for result in queen(num,state+(pos,)):yield (pos,)+result
li=list(queen(4))
print(li)[(1, 3, 0, 2), (2, 0, 3, 1)]

附录A:到时待办

  • 下载使用Sublime Text 3,用来编写Python代码;
  • 下载使用Visual Studio Code,用来编写Python代码;
  • 下载学习使用并适应使用PyCharm;
  • 将列表转换成字符串 ’ '.join(somelist);
  • 尝试使用string模块中的模板字符串Template().substitute(foo)进行格式化
  • - 用生成器解决八皇后问题还需要继续理解一下,特别是相比return

附录B:资料

  • 1、Github100天学Python项目:https://github.com/jackfrued/Python-100-Days
  • 2、菜鸟教程 python 3 教程:https://www.runoob.com/python3/python3-tutorial.html

Python学习笔记 之 从入门到放弃相关推荐

  1. python复数的实部和虚部都是整数嘛_Python学习笔记:从入门到放弃(2)基本语法...

    这次主要就记录一下Python中的基本语法,有标识符,注释,行与缩进,print函数输出以及数字类型和字符串 标志符: 第一个字符必须是字母表中字母或下划线 _ . 标识符的其他的部分由字母.数字和下 ...

  2. python中复数的实部和虚部都是浮点数_Python学习笔记:从入门到放弃(2)基本语法...

    这次主要就记录一下Python中的基本语法,有标识符,注释,行与缩进,print函数输出以及数字类型和字符串 标志符: 第一个字符必须是字母表中字母或下划线 _ . 标识符的其他的部分由字母.数字和下 ...

  3. Python学习笔记—低阶入门(已完结)

    目录 前言 注意 该不该学习Python(个人感受,纯属胡言论语) 基础知识:Python 的数据存储机制 第一章 Python基本语法 1.1 Python 数据类型 1.1.1 数值类型 1.1. ...

  4. Python学习笔记--day10函数入门

    day10 函数入门 初识函数 函数的参数 函数的返回值 1. 初识函数 函数到底是个什么东西? 函数,可以当做是一大堆功能代码的集合. def 函数名():函数内编写代码......函数名() 例如 ...

  5. (二)python学习笔记之列表入门

    1.列表元素的访问 test=[1,2,3,4,5] print(test[1])#列表元素的访问 2.列表的基本操作方法 test=[1,2,3,4,5] test.append(6) # 在列表末 ...

  6. Python学习笔记--10.Django框架快速入门之后台管理admin(书籍管理系统)

    Python学习笔记--10.Django框架快速入门之后台管理 一.Django框架介绍 二.创建第一个Django项目 三.应用的创建和使用 四.项目的数据库模型 ORM对象关系映射 sqlite ...

  7. Python 学习笔记——入门

    文章目录 〇.Python 是什么 一.推荐的教程 二.这篇学习笔记适合什么人 三.环境 1. 操作系统 对于 Windows 对于 Ubuntu 对于其他操作系统 2. Python 对于 Wind ...

  8. Python学习笔记之入门基础

    课程链接:Python入门教程--基础阶段_哔哩哔哩_bilibili Python学习笔记 注释 单行注释: * 多行注释: 1.多行前面加# 2."""注释信息&qu ...

  9. [python教程入门学习]python学习笔记(CMD执行文件并传入参数)

    本文章向大家介绍python学习笔记(CMD执行文件并传入参数),主要包括python学习笔记(CMD执行文件并传入参数)使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋 ...

最新文章

  1. Gradle 学习二
  2. mac笔记本怎么外接显示屏_苹果MAC笔记本怎么外接显示器?
  3. 详解JDBC连接数据库
  4. 系统即将关机请保存关机是由nt_设置Windows电脑自动关机
  5. 《图解深度学习》图书及代码,16章带你无障碍深度学习
  6. 基于bootstrap模态框的日期选择器
  7. 18 File Duplication and Pipes
  8. python怎么实现黑客攻击英国_注意!你的隐私就是这样被黑客获取的
  9. 【安卓的一个进程等级】
  10. 电子学会图形化三级编程题解析含答案:冬天下雪了
  11. .NET简谈分层架构思想(彻底分离每个层)
  12. NLP - snownlp
  13. 主流微信编辑器对比,最好用的竟然是它!
  14. WP模板阁怎么样?能买吗
  15. 《鸟哥的Linux私房菜》Chapter11 20180726~20180806
  16. Adobe突然查封中国账号,设计社区Behance无权访问!
  17. 目标跟踪评估绘图(3):ubuntu18.04在MATLAB2016b下的vot-toolkit配置,绘制VOT数据集的EAO评估图,与其他算法进行比较
  18. 重置Windows打印机COM端口USB端口
  19. 如何修改本机host地址
  20. Google分布式系统三大论文(二)Bigtable: A Distributed Storage System for Structured Data

热门文章

  1. python语言实验指导答案_Python实验指导书
  2. VMware 虚拟机怎么连接U盘
  3. 计算机计算芯片原理,集成电路-CPU运行基本原理 CPU是计算机的核心,弄清楚CPU的运行基本原理,也就明白了计算机系统中各种芯片的数据处理和存储功能是如何实现。 在往期... - 雪球...
  4. 《趣学算法》Chapter 2 贪心算法
  5. SoO of EIGRP
  6. FDTD快速入门之Lumerical脚本语言Pickup——参考资料
  7. 兆信rxn305d使用说明书_直流电源 RXN-305D-II
  8. Kali Linux三种网络攻击方法总结(DDoS、CC和ARP欺骗)
  9. Android多线程和异步任务
  10. webmatrix mysql_WebMatrix教程(一) (关注Microsoft 的最新武器:建立你的第一个WebMatrix网站)...