Python学习
Mac退出命令行模式control+D
基本数据类型
进制转换
0b表示二进制
0o表示八进制
0x表示十六进制
>>> 0b10
2
>>> 0o10
8
>>> 0x10
16
number类型
bin表示把其他类型的数据转换为二进制
>>> bin(10)
'0b1010'
>>> bin(0b1010)
'0b1010'
>>> bin(0o100)
'0b1000000'
>>> bin(0x122)
'0b100100010'
int()表示转换为10进制,hex()表示转换为16进制,oct()表示转换为8进制
数据类型:bool属于Number,bool()可以把数字转成True或者False,只有0或者’’其他表示空含义的表示False,False表示空的,bool(None)表示False,36j表示复数
转义字符
>>> 'hello\
world'
'helloworld'
\n是换行 \r回车
转义地址路径
>>> print('c:\aa\bb\cc')
c:ab\cc
>>> print('c:\\aa\\bb\\cc')
c:\aa\bb\cc
>>> print(r'c:\aa\bb\cc')
c:\aa\bb\cc
r或者R表示原始字符串
字符串str
>>> 'hello '*5
'hello hello hello hello hello '
>>> 'hello world'[2]
'l'
>>> 'hello world'[7]
'o'
>>> 'hello world'[-1]
'd'
>>> 'hello world'[1:5]
'ello'
>>> 'hello world'[0:-1]
'hello worl'
>>> 'hello world'[0:-5]
'hello '
>>> 'hello world'[6:]
'world'
>>> 'hello world'[0:5]
'hello'
>>> 'hello world'[2:5]
'llo'
>>> 'hello world'[-5:]
'world'
截取时,正数代表从前往后数的索引位置,复数代表从后往前数第几个位置。
列表
列表可以支持多种数据类型,支持嵌套列表
>>> ['汉字','中国',1,3,4,True,False,True][1]
'中国'
>>> ['汉字','中国',1,3,4,True,False,True][3]
3
>>> ['汉字','中国',1,3,4,True,False,True][6]
False
>>> ['汉字','中国',1,3,4,True,False,True][-2]
False
>>> ['汉字','中国',1,3,4,True,False,True][1:4]
['中国', 1, 3]
>>> ['汉字','中国',1,3,4,True,False,True][-2:-1]
[False]
>>> ['汉字','中国',1,3,4,True,False,True][-3:]
[True, False, True]
>>> ['汉字','中国',1,3,4,True,False,True]*3
['汉字', '中国', 1, 3, 4, True, False, True, '汉字', '中国', 1, 3, 4, True, False, True, '汉字', '中国', 1, 3, 4, True, False, True]
注意:使用带:的的形式获取,返回的还是list,使用单一的索引的话获取的是list的值,这一点在编码的过程中很容易报错,尽管可以检查出来,但是还是应该保持好的编码习惯。
元组tuple
>>> (1,2,'kai',"shi",True,False)[2]
'kai'
>>> (1,2,'kai',"shi",True,False)[0:3]
(1, 2, 'kai')
>>> (1,2,'kai',"shi",True,False)[-3:-1]
('shi', True)
可以看见,tuple和list差不多,但是有区别,tuple是不可变的,类似于java中的数组
注意,如何创建具有单个元素的元组(IDLE会把其认为是运算时候的括号,所以做了硬性规定,单个元组后面需要加,逗号)
>>> type((1))
<class 'int'>
>>> type((1,))
<class 'tuple'>
>>> type(("hello"))
<class 'str'>
>>> type(("hello",))
<class 'tuple'>
数据类型总结:str
, list
,tuple
都是序列,都是有序的,都有序号,以后还有无序的。
序列相关方法,in, not in,min(),max(),len()
>>> 3 in (1,2,34,5)
False
>>> 3 not in (1,2,345)
True
>>> len((1,2.3,4))
3
>>> len([2,1,"kai","shi"])
4
>>> min([1,2,3])
1
>>> max((1,2.3,45,6))
45
>>> min("hello world")
' '
>>> max("hello world")
'w'
序列比较字母是通过ASCII码实现的,获取字母的ASCII码的方法如下:
>>> ord('d')
100
>>> ord('w')
119
>>> ord(' ')
32
>>> ord("1")
49
集合set
集合的特点:无序,不重复,不能切片,in(),len()这些方法都可以使用,集合还有并集|,交集&的运算
>>> type({1,2,3})
<class 'set'>
>>> 2 in {1,2,3}
True
>>> len({1,2,3,4})
4
>>> max({1,2,3})
3
>>> {1,2,3,4} - {1,2}
{3, 4}
>>> {1,2,3,4} & {2,3}
{2, 3}
>>> {1,2,3,4} | {1,5,6}
{1, 2, 3, 4, 5, 6}
定义空的set集合,使用set()
>>> type(set())
<class 'set'>
>>> len(set())
0
字典dict
dict和map类似,不能重复相同的key,访问value通过[]来实现
key的类型可以为int,str,key必须是不可变的类型,list是不可以的,tuple是可以的
value的类型可以为str,int,float,list,set,dict
>>> {'key':'value',1:1,3:3}
{'key': 'value', 1: 1, 3: 3}
>>> type(dict())
<class 'dict'>
>>> {1:1,'1':"chuan"}
{1: 1, '1': 'chuan'}
# 可以
>>> {1:1,'1':"chuan"}['1']
'chuan'
>>> {1:1,'1':"chuan",3:(1,2,3,4)}
{1: 1, '1': 'chuan', 3: (1, 2, 3, 4)}
>>> {1:1,'1':"chuan",3:(1,2,3,4)}[3]
(1, 2, 3, 4)
>>> {(1,2):1,'1':"chuan",3:(1,2,3,4)}
{(1, 2): 1, '1': 'chuan', 3: (1, 2, 3, 4)}
基本数据类型总结

变量与运算符
语法规定:变量名要是字母,数字,下划线,但是不能使用数字开头,也不能使用python来命名,变量名是可以区分大小写的,这也正说明了python是动态语言。
# pytho保留关键字:
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
规范一点,尽量不使用type作为变量类型
基本数据类型被改变以后,不影响之前的变量的值,引用类型改变以后,之前赋值的变量的值会被改变。
# 证明str是不可变的
>>> b = 'name';
>>> id(b)
4326024504
>>> b = b + "user"
>>> print(b)
nameuser
>>> id(b)
4663953712
>>> hex(id(b))
'0x115fe4930'
内存地址一般使用16进制表示,一般不使用10进制来表示
# 证明list是可以改变的,添加一个元素,还是在原来的内存地址
>>> a = [1,2,3]
>>> id(a)
4663952648
>>> a.append(4)
>>> id(a)
4663952648
元组中的list是可以改变的,如下:
>>> a = (1,2,3,[11,12,14,15])
>>> a[3][2]=24
>>> print(1)
1
>>> print(a)
(1, 2, 3, [11, 12, 24, 15])
例子:会先计算>=,true在python里面是1
>>> b = 1
>>> b+=b>=1
>>> print(b)
2
# list,tuple逻辑运算
>>> [1,2,3] <[1,2,4]
True
>>> (1,2,4) > (1,2,3)
True
# bool运算
>>> not True
False
>>> not not True
True
# 需要执行第二个元素才能确定结果
>>> 'a' and 'c'
'c'
# 执行第一个元素就知道结果了,所以直接返回a
>>> 'a' or 'd'
'a'
# in 在dict中是针对key,而不是value
>>> b = 'bb'
>>> b in {'bb':'cccccc'}
True
# 身份运算符,is比较的是内存地址
>>> a=1
>>> b=1.0
>>> a==b
True
>>> a is b
False
# 类型判断,还是推荐使用isinstance
>>> type(a) == str
True
>>> a='strr'
>>> isinstance(a,str)
True
>>> isinstance(a,(str,int,float))
True
IDE编辑代码
主流pychrm,vscode,sublime,本次使用vscode
基本操作
打开设置:code-首选项-设置
control+~
:打开Terminal
文件右键-在终端中打开,可以直接进入这个文件所在的目录
流程控制语句
if else
# 未优化
a = input()
print(type(a))
if a == 1:
print("one")
else:
if a == 2:
print("two")
else:
if a == 3:
print("three")
else:
print("four")
# 优化后 使用elif
a = input()
print(type(a))
if a == 1:
print("one")
elif a == 2:
print("two")
elif a == 3:
print("three")
else:
print("four")
python项目结构
包,模块,类(方法,变量)
在python下:如果想让一个文件夹变成一个包,下面需要用一个__init__.py
的文件
模块的内置,内置属性属性:__all__
= [‘a’,‘c’]
python导入模块的时候会先执行这个模块的内容;
一个.py文件可以认为是一个模块,里面可以包含多个类,但是在开发的时候还是建议一个模块定义一个类
函数
序列解包的时候,直接接收返回的两个结果,例如使用n个变量来接收n个长度的tuple
参数
- 必需参数,必需传入
- 关键字参数,函数调用时,实际指定使用什么形参进行接收,可以提高代码的可读性。
- 默认参数,指定形参默认值,默认参数只能放在最后面,跳跃赋值的时候可以使用关键字参数进行指定
类的方法
类的方法必须加self,调用成员变量使用self.name
类的设计其实可以认为包含行为与特征
构造函数
实例方法必须指定self,类似于this,就是指当前对象
def __init__(self):
print('construt')
# 将类变量的值复制给实例变量,会先查找实例变量,再查找类变量,再查找夫类
def __init__(self,name,age):
name = name
age = age
print('construt')
# 将实例变量的值赋给对象
def __init__(self,name,age):
self.name = name
self.age = age
print('construt')
打印当前对象的值:
student1.__dict__
,返回{}
在实例方法中访问实例变量,self.name
,不建议直接使用name
访问类变量:Student.sum1
或者self__class__sum1
类方法需要加上@classmethod,有点类似于其他方法的静态方法
# 定义类方法
@classmethod
def plus_sum(cls):
cls.sum += 1
print(cls.sum)
# 调用类方法
Sudent.plus_sum()
# 尽管实例对象可以调用类方法,但是不推荐,这样写不规范
student.plus_sum()
静态方法需要加上@staticmethod,不需要传入cls或者self
@staticmethod
def add(x,y):
print('this is a static method')
似有方法方法或者变量使用__开头
student.__score = -1会创建一个新变量
封装继承多态
实现继承
import c6
class Student(c6.People):
...
# 或者,推荐
from c6 import People
class Student(People):
...
python支持多继承
子类调用父类的构造
def __init__(self,school,name,age):
self.school = school
Human.__init__(self,name,age)
# 或者 推荐
super(Stunent,self).__init__(self,name,age)
python可以通过类调用实例方法,但是不推荐。
子类与父类有同名方法,会调用父类方法
super(Stunent,self).dohomework
python在3.4以后才加入的枚举
python高级语法与用法
函数可以作为返回,闭包 = 函数 + 环境变量,闭包是函数式编程的体现。
闭包在写第三方类库的时候推荐使用,在写业务代码的时候不推荐使用。
然后f = curve_pre
,调用f(2)
定义匿名函数(lambda)表达式
# 普通函数
def add(x,y):
return x+y
# 匿名函数
lambda x,y:X+y
# 调用匿名函数
f = lambda x,y:X+y
print(f(1,2))
三元表达式
条件为真的时候的结果 if 条件判断 else 条件为假的时候的结果
map类:map会接收集合的每一个元素,映射成某一个结果
r=map(square,list )
map,reduce,filter
上面三个是常用的lambda的函数(lisp函数式编程的鼻主,在人工智能常用)
函数式编程结合map:
list_x = [1,2,3,4,5,6,7,8]
r = map(lambda x: x*x,list_x)
print(r)
python中的*表示可变参数
list_x = [1,2,3,4,5,6,7,8]
list_y = [1,2,3,4,5,6,7,8]
r = map(lambda x,y: x*x + y,list_x,list_y)
print(r)
[2, 6, 12, 20, 30, 42, 56, 72]
from functools import reduce
# 连续计算,将前一个的计算结果作为函数的参数继承传入,直至遍历结束
list_x = [1,2,3,4,5,6,7,8]
r = reduce(lambda x,y:x+y,list_x)
# 一般返回时都是使用list返回
print(list(r))
# (((1+2)+3)+4)+5
谷歌在大数据提出了一个map/reduce 的编程模型,代表映射,规约,主要是为了进行并行计算/其就借鉴了lambda表达式函数式编程的思想。
filter
list_x = [1,2,3,4,5,6,7,8]
r = filter(lambda x:x<7,list_x)
print(list(r))
[1, 2, 3, 4, 5, 6]
装饰器
装饰器其较常用的,装饰器类似于注解,首先定义装饰器,在定义函数的时候调用这个装饰器
python提供了这个语法糖
import time
def decorator(func):
def wrapper():
print(time.time())
func()
return wrapper
@decorator
def f1():
print("It's a function as f1() ")
f1()
1557648258.44
It's a function as f1()
定义支持不同个数参数的装饰器
import time
def decorator(func):
def wrapper(*args):
print(time.time())
func(*args)
return wrapper
@decorator
def f1(func_name):
print("It's a function as f1() "+func_name)
@decorator
def f2(func_name1,func_name2):
print("It's a function as f1() "+func_name1)
print("It's a function as f1() "+func_name2)
f1("test1")
f2("test2","test3")
1557649090.21
It's a function as f1() test1
1557649090.21
It's a function as f1() test2
It's a function as f1() test3
处理关键字参数的装饰器(注意*args,**kw
这个小技巧)
import time
def decorator(func):
def wrapper(*args,**kw):
print(time.time())
func(*args, **kw)
return wrapper
@decorator
def f1(func_name):
print("It's a function as f1() "+func_name)
@decorator
def f2(func_name1,func_name2):
print("It's a function as f1() "+func_name1)
print("It's a function as f1() "+func_name2)
@decorator
def f3(func_name1,func_name2,**kw):
print("It's a function as f1() "+func_name1)
print("It's a function as f1() "+func_name2)
print(kw)
f1("test1")
f2("test2","test3")
f3("test2","test3",a=1,b=2,c="123")
其他补充(装饰器)
python开发web的web框架flask
@api.route('/psw',method=['GET'])
def test_javascrip_http():
p = request.args.get('name')
return p,200
@api.route('/psw',method=['GET'])
@auth.login_required
def get_pwd():
p = request.args.get('psw')
r = generate_password_hash(p)
return 'aaaaaa',200
爬虫实战
断点调试
F5开始调试或者进入下一个断点
F10单步执行
F11进入方法内部
一般选择闭合标签,目标标签的父类标签。
正则表达式
匹配所有字符至少有三种写法
\w 匹配单词字符,\W 匹配非单词字符,一起使用可以匹配所有字符
\s 匹配空白字符,\S 匹配非空白字符,一起使用可以匹配所有字符
. 匹配除换行符\n之外其他所有字符