Python学习笔记 之 从入门到放弃

2023-11-02

笔记目录

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.141593
      3.14
     abcde
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      abcd
   10
  -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:
		break
	print ('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 = 0
	def 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 = 0
	def submethod(self):
		self.id = 0
		print('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 = True
	def eat(self):
		if self.hungry:
			print("Aaaah...")
			self.hungry = False
		else:
			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异常)

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

·属性

# 定义一个类
class A(object):
 
    # 类属性,直接在类中定义的属性是类属性
    #   类属性可以通过类或类的实例访问到
    count = 0
 
    def __init__(self):
        # 实例属性,通过实例对象添加的属性属于实例属性
        #   实例属性只能通过实例对象来访问和修改,类对象无法访问修改
        self.name = '孙悟空'
        self.count += 1				#这里self.count和A.count是不同的,A.count是类属性,self.count是实例属性
 
    # 实例方法
    #   在类中定义,以self为第一个参数的方法都是实例方法
    #   实例方法在调用时,Python会将调用对象作为self传入  
    #   实例方法可以通过实例和类去调用
    #       当通过实例调用时,会自动将当前调用对象作为self传入
    #       当通过类调用时,不会自动传递self,此时我们必须手动传递self
    def test(self):
        print('这是test方法~~~ ' , self)    
 
    # 类方法    
    # 在类内部使用 @classmethod 来修饰的方法属于类方法
    # 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象
    #   类方法和实例方法的区别,实例方法的第一个参数是self,而类方法的第一个参数是cls
    #   类方法可以通过类去调用,也可以通过实例调用,没有区别
    @classmethod
    def test_2(cls):
        print('这是test_2方法,他是一个类方法~~~ ',cls)
        print(cls.count)
 
    # 静态方法
    # 在类中使用 @staticmethod 来修饰的方法属于静态方法  
    # 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用  
    # 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数
    # 静态方法一般都是一些工具方法,和当前类无关
    @staticmethod
    def 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 = 0
	def __next__(self):				#使用next函数会出错误,必须使用__next__函数
		self.value += 1
		if self.value > 10:
			raise StopIteration
		return self.value
	def __iter__(self):
		return self					#返回自身
		
ti1 = TestIterator()
for v in ti1:
	if v>5 :
		print(v)
		break

ti2 = 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:
			pass
		else:
			raise TypeError			#而是把字符串当成一个整体原子值

		for sublist in nested:
			for element in flatten(sublist):		#这利用了递归处理嵌套多层的列表
				yield element
	except TypeError:
		yield nested

nested = [[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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python学习笔记 之 从入门到放弃 的相关文章

  • Python 中的字节数组

    如何在 Python 中表示字节数组 如 Java 中的 byte 我需要用 gevent 通过网络发送它 byte key 0x13 0x00 0x00 0x00 0x08 0x00 在Python 3中 我们使用bytes对象 也称为s
  • 如何将base64字符串直接解码为二进制音频格式

    音频文件通过 API 发送给我们 该文件是 Base64 编码的 PCM 格式 我需要将其转换为 PCM 然后再转换为 WAV 进行处理 我能够使用以下代码解码 gt 保存到 pcm gt 从 pcm 读取 gt 保存为 wav decod
  • 如何使用 pyinstaller 包含文件?

    我也使用 tkinter 使用 python 3 7 编写了一个程序 由于我使用的是外部图片 因此当我将所有内容编译为一个 exe 时 我需要包含它们 我试过做 add data bg png files 但我仍然收到此错误 tkinter
  • PyQt:如何通过匿名代理使用网页

    这真让我抓狂 我想在 QWebPage 中显示一个 url 但我想通过匿名代理来实现 Code setting up the proxy proxy QNetworkProxy proxy setHostName 189 75 98 199
  • 即使页面未完全加载,我们也可以使用 Selenium 获取页面源吗(TimeoutException: Message: timeout)?

    即使遇到 TimeoutException Message timeout 也能获取页面源码吗 当我调用 driver page source 时 有时无法加载整页 但我只需要它的部分信息 尚未确定 所以我只想在任何情况下保存页面 是否可以
  • Python有条件求解时滞微分方程

    我在用dde23 of pydelay包来求解延迟微分方程 我的问题 如何有条件地编写方程 例如目标方程有两个选项 when x gt 1 dx dt 0 25 x t tau 1 0 pow x t tau 10 0 0 1 x othe
  • Python在postgresql表中查找带有单引号符号的字符串

    我需要从 psql 表中查找包含多个单引号的字符串 我当前的解决方案是将单引号替换为双单引号 如下所示 sql query f SELECT exists SELECT 1 FROM table name WHERE my column m
  • Jupyter Notebooks 不显示进度条

    我正在尝试在 Jupyter 笔记本中显示进度条 这是一台新电脑 我通常做的事情似乎不起作用 from tqdm import tqdm notebook example iter 1 2 3 4 5 for rec in tqdm not
  • 如何使用显式引用转储 YAML?

    递归引用非常适合ruamel yaml or pyyaml ruamel yaml dump ruamel yaml load A A id001 id001 然而 它 显然 不适用于普通引用 ruamel yaml dump ruamel
  • 如何在 PyCharm 4.5.2 中使用 PyPy 作为标准/默认解释器?

    如何在 PyCharm 4 5 2 中使用 PyPy 作为标准 默认解释器 一切都在 Ubunutu 14 10 下运行 并且 pypy 已经安装 您可以在项目的设置下进行配置 这个官方文档直接涵盖了 https www jetbrains
  • 在 macOS 中通过 Python 访问进程的压缩 RAM(顶部的 CMPRS)的方法?

    我试图弄清楚如何从 Python 访问任何给定进程占用的实际 RAM 量 我发现 psutil Process PID memory info rss 工作得很好 直到操作系统决定开始压缩某些进程的 RAM 然后 所有的 memory in
  • numpy 使用 datetime64 进行数字化

    我似乎无法让 numpy digitize 与 datetime64 一起使用 date bins np array np datetime64 datetime datetime 2014 n 1 s for n in range 1 1
  • 可以用 Django 制作移动应用程序吗?

    我想知道我是否可以在我的网站上使用 Django 代码 并以某种方式在移动应用程序 Flutter 等框架中使用它 那么是否可以使用我现在拥有的 Django 后端并在移动应用程序中使用它 所以就像models views etc 是的 有
  • Apache Spark 中的高效字符串匹配

    我使用 OCR 工具从屏幕截图中提取文本 每个大约 1 5 句话 然而 当手动验证提取的文本时 我注意到时不时会出现一些错误 鉴于文本 你好 我真的很喜欢 Spark 我注意到 1 像 I 和 l 这样的字母被 替换 2 表情符号未被正确提
  • 动态 __init_subclass__ 方法的参数绑定

    我正在尝试让类装饰器工作 装饰器会添加一个 init subclass 方法到它所应用的类 但是 当该方法动态添加到类中时 第一个参数不会绑定到子类对象 为什么会发生这种情况 举个例子 这是可行的 下面的静态代码是我试图最终得到的示例 cl
  • 如何使用 paramiko 查看(日志)文件传输进度?

    我正在使用 Paramiko 的 SFTPClient 在主机之间传输文件 我希望我的脚本打印文件传输进度 类似于使用 scp 看到的输出 scp my file user host user host password my file 1
  • Python 类型安全吗?

    根据维基百科 https en wikipedia org wiki Type system Type safety and memory safety 如果一种语言不允许违反类型系统规则的操作或转换 计算机科学家就认为该语言是 类型安全的
  • 如何使用 Keras ImageDataGenerator 预测单个图像?

    我已经训练 CNN 对图像进行 3 类分类 在训练模型时 我使用 keras 的 ImageDataGenerator 类对图像应用预处理功能并重新缩放它 现在我的网络在测试集上训练得非常准确 但我不知道如何在单图像预测上应用预处理功能 如
  • 处理大文件的最快方法?

    我有多个 3 GB 制表符分隔文件 每个文件中有 2000 万行 所有行都必须独立处理 任何两行之间没有关系 我的问题是 什么会更快 逐行阅读 with open as infile for line in infile 将文件分块读入内存
  • 如何获取所有mysql元组结果并转换为json

    我能够从表中获取单个数据 但是当我试图获取表上的所有数据时 我只得到一行 cnn execute sql rows cnn fetchall column t 0 for t in cnn description for row in ro

随机推荐

  • Go语言学习-- No.12 结构体-- 匿名结构体的定义和初始化

    匿名结构体的定义和初始化 匿名结构体的定义和初始化 匿名结构体的定义和初始化 匿名结构体无须type关键字就可以直接使用 且不用写出类型名称 匿名结构体在创建的同时也要创建对象 匿名结构体在初始化时需进行匿名结构体定义和成员变量初始化 举例
  • 适配小程序隐私保护指引设置

    由于小程序发布了一个公告 那么接下来就是怎么改简单的问题了 毕竟不太想大的改动历史上的代码 尽量简单的适配隐私策略就可以了 整体思路也是参考现在App普遍的启动就让用户同意隐私策略 不同意不让用 同意了之后才能够继续使用 公告内容 参考文档
  • OpenGL GLFW入门篇 - 画点集

    效果图 主体代码 void DrawPoints void int i GLfloat x y glPushMatrix 另一个相对的Z平移可以分离对象 glLoadIdentity glTranslatef 0 0 0 0 0 f 设置点
  • maven release版本重复上传error

    A couple things I can think of user credentials are wrong url to server is wrong user does not have access to the deploy
  • 【2023】华为OD机试真题Java-题目0209-找出通过车辆最多颜色

    找出通过车辆最多颜色 题目描述 在一个狭小的路口 每秒只能通过一辆车 假如车辆的颜色只有3种 找出 N N N 秒内经过的最多颜色的车辆数量 三种颜色编号为0 1 2 输入描述 第一行输入的是通过的车辆颜色信息 0 1 1 2 代表4秒钟通
  • python识别视频中火焰_监控视频中火焰检测算法

    基于视频的火焰的检测 如果通过采集监控摄像头的画面 监控广大区域 发现着火区域 能够快速报警的话 就可以有效提高监控的效果 提早报警 大大减少财产损失和人员伤亡 我们视觉上发现火灾的途径有2个 通过观察火焰 及时发现火灾 通过观察烟雾 及时
  • 【前端面试】VUE面试常问(内含个人整理与总结)

    我为什么选择vue 个人感觉编码方式和html差别不大 上手很块 对新手友好 vue与react的比较 React是库 Vue则是完整的框架相同点 都是数据驱动视图 都遵循组件化思想 遵循基于可重用组件的方法 提供component方法 都
  • 【深度学习】——如何提高map值

    目录 代码获取 map原理 map提高技巧 技巧总结 实战 1 效果不佳map55 55 1 单独调整get dr txt py中的self iou 0 3 2 单独调整get map py中的minoverlap 3 同时调整minove
  • 修改vscode的exe生成位置

    修改vscode的exe生成位置 概述 注意 修改task json文件 修改launch json文件 概述 在windows系统使用vscode学习C 时 调试的时候会在cpp文件的目录里生成一个exe文件 造成文件很多 有点乱 就想着
  • '2.587426955E9' in column '2' is outside valid range for the datatype INTEGER.

    今天在展现人员信息时遇到这个错误 2 587426955E9 in column 2 is outside valid range for the datatype INTEGER 在网上查了 说是超出了INTEGER的最大长度 后经实践检
  • java 将图片转为base64返回给前端

    一 controller端代码 RequestMapping value captcha public void imagecode HttpServletRequest request HttpServletResponse respon
  • vue:前端接收并展示后端返回的一个图片对象(文件流)

    需求 前端接收并展示后端返回的一个图片对象 文件流 没有图片的时候 显示默认图片 1 HTML 造空间 展示图片 div class qrcodeBox img div 2 定义变量 这里require的作用是设置默认图片 data ret
  • H5页面在ios的浏览器上使用 高德地图 报当前定位失败Geolocation permission denied 或者 偶尔报AMap没有找到的

    1 解决报当前定位失败Geolocation permission denied 可以去高德api查看 常见问题 高德地图API amap com 图中红圈2 3 4 5 6对应Geolocation permission denied报错
  • JDBC中获取连接的几种方式,快来看看吧

    注 下面的连接均是以mysql为例 Test是Junit4的注解用于测试 Properties不会的话可自行百度 可能存在某些不规范的说法或者错误 恳请各位指出错误 方式一 import com mysql cj jdbc Driver i
  • Java模拟formdata发送请求-文件上传

    public String upload HttpHeaders httpHeaders RestTemplateUtils basicAuthenticationInfo poAuthConfig getUsername poAuthCo
  • java爬虫爬取主流房屋网站

    最近博主要做一些分析课题 所以使用java爬取了主流的房屋网站 搞些事情 下面是我搞事情的思路 在结尾处我会投放我的源码文件 供大家下载 导航 设计思路 项目的包与类详解 部分重要代码展示 源码下载 设计思路 想要爬取房屋的网站 就要有以下
  • ELM和RVFL两种网络的超详细介绍

    最近一直在跑程序 在看文章时注意到了这两种网络 ELM和RVFL 自己查阅资料做了简单的总结 希望在大家学习时帮助到大家 一 RVFL Random vector functional link network 首先明确一点 在进行分类的时
  • 【学习记录】win10 + ubuntu 22.04双系统安装

    一 背景 因为家里的台式 Windows 10 最近一直频繁蓝屏 再加上Win10之前经常性的资源管理器未响应 对Windows系统逐渐失去了信心 于是想着安装稳定性较好的Linux 以前抵触Linux是因为其人机交互界面没Windows那
  • Rabbit MQ使用

    rabbitmq支持 net framwork 3 5的最后版本 rabbitmq支持 net framwork 3 5的最后版本是3 4 3 安装步骤 1 工具 gt 库程序包管理器 进入程序包管控制台 2 Install Package
  • Python学习笔记 之 从入门到放弃

    笔记目录 9月22日 基础教程 基础知识 模块导入 用变量引用函数 或者Python中大多数的对象 将数值转换成字符串的方法 str类型 repr函数 9月23日 列表 元组 序列索引可以为负数 序列的分片和步长 序列相加 乘法 列表和字符