Python
概述
简介
- python是一种解释性,面向对象,动态数据类型的高级程序语言,
- 解释型,无编译过程,逐行解释为二进制
- 交互性,直接执行程序
- 应用广泛,
- 编译型:一次将所有编译为二进制
特点
- 易于学习
- 易于维护
- 易于阅读
- 广泛的标准库
- 互动模式
- 可移植
- 可扩展:兼容c语言,可调用
- 数据库
- GUI编程
- 可嵌入,c调python
缺点
- 运行慢:代码一行一行翻译成CPU理解的机器码运行,即一行一行运行,很慢; 而C语言直接翻译后成执行的机器码,很快 编程任务: io型:复制,打开网页,所以说虽然速度慢,依然使用它 计算型:数据计算,用c 快
- 代码不能加密:只能发布源代码,不能编译
- 没有多线程
Python分类
推荐cpython, py->c语言的字节码->0000010101
jypython, py->java的字节码
ironpython,
其他语言的python
pypy, 一次性编译为py的字节码,速度快,开发效率相对低-->0101
这只是python解释器的分类,python语法规范相同
代码语言:javascript复制#-*- encoding:utf-8 -*-
# coding=utf-8 都可以
print("段志方")
#python2不支持中文默认是ascii
variable
字母数字下划线,空格不行,中文可以(但不要这样) 同java
a=12
b=a
c=b
b=100
print(a,b,c)->12,100,12
因为逐行执行
注释
单行注释:# 读,但不运行
多行注释:'''xxxx''' 或"""xxxx"""
数据交互,input
name=input("xxxx")
type(name)->str 全是字符串
数据类型
- 数字 type(100) -><class 'int'>
int
- 范围根据电脑变化 -2^31~2^31-1 32位
- 64位 31 换63即可 long 长整型 python3中没有全是int python2中有
- 字符串str:单引双引
可相加,可相乘 与数字
"段志方"*8
msg='''
xxx
yyy
zzz
'''也可三个双引号
- bool 布尔值:首字母大写 此时不是注释,里面格式不变 与字符串转换 空串为false 否则为true 与list,元祖,只要是空都是False
- list:类型可不一致,储存大量数据
- 元组(只读列表):(1,2,3,"xxx")可存任何数据
- 字典dict:键值对 {"name":"段志方","age":21}也可大量数据,不限类型 如列表中有列表时可用lis[x][y]取出
- 集合:{1,2,3,"xxx"} 可求交集,差集
条件语句
if 条件:
4空格或tab 但不要混用
代码语言:javascript复制if True:
print(1)
print(2)
#都打印
if True:
xxx
else:
yyy
if a :
elif b :
elif c:
else:
while
代码语言:javascript复制#break continue 照样适用
while True:
print()
while .... else
正常执行完毕会执行else
被break打断不会执行else
代码语言:javascript复制count = 0
while count < 5:
count = 1
print(count)
break
else:
print("while->else")
for循环
s=字符串,列表等可迭代元素
for i in s:
print(i)
if "xxx" in s:
pass
not in
字符串与数字转换
str='1'
b=int(str) b变为int
str(int) 数字转换为字符串
格式化输出
转义字符是"%" %%表示正常输出%
代码语言:javascript复制#格式化输出
#% s d
name = input("input your name:")
age = input("input your age:")
height = input("input your height:")
msg = "My name is %s, I'm %s years old,%scm tall" % (name, age, height)
msg2 = '''-----------------------------
name:%s
age:%s
height:%s
-----------------------------
''' % (name, age, height)
print(msg)
print(msg2)
编码
ascii 初期 包含字符少只有7位 预留了第一位全为0
unicode
最开始
1字节表示所有英文,数字,特殊符号
2字节表示中文 ,不够,
后来全部使用32位表示英文与中文都是
升级->utf-8(一个字符最少8位) utf16 同理
中文3字节
英文1字节
欧洲文字2字节
gbk 中文2字节
英文1个字节
文件的储存与传输不能是unicode,只能是其他的几种
py3:str在内存中是使用unicode编码的,所以文件存取要转换
bytes类型 编码方式 ascii,utf-8,gbk等
所以str直接存储到文件传输,不可以
英文
str:表现方式 s="dzf“
编码方式 unicode 00001000 ...
bytes 表现方式 s=b"dzf"
编码 gbk 01000001...
中文
str同上
bytes表现方式=b"xe1xd5xa5" 3个字节表示
s="dzf".encode("utf-8") 为bytes类型 (将dzf转为bytes类型,utf-8编码方式)
s="段志方".encode("utf-8")->b'xe6xaexb5xe5xbfx97xe6x96xb9'
运算符
,-,**,/ ,//
逻辑运算符(数字比较时想象为true,false即可)
注意没有"||" "&&"
&表示位运算符 当数字&时 与and不同 表示的是二进制相与
()>not >and >or
x or y
x为非零(真) 结果为x
x为零(假) 结果为 y
数字与bool可直接比较
x and y
x不为0 返回y
x为0 返回 x
int(True)=1
bool(1)=True
字符串常用操作方法
字符串切片
s[n]获取索引n的字符
获取一段s[m:n]字符串切片,顾头不顾尾
s[-1]从后向前
s[-2:-5] 从后向前
s[0:-1]不包含最后一个
s[:]=s[0:]全部
s[n:n]空
s[0:10:2]0到10内每隔2个取一个
s[4:0:-2]倒着取,没2个取一个
注意不能s[4:0]
str.capitalize() 首字母大写 数字无影响
upper() 全部大写
lower()全部小写
swapcase()大小写反转
title() "dzf非英文zbcd"->"Dzf非英文Zbcd"
center(n,"#")设置字符串长度为n,两边#填充 居中显示
expandtabs() 补全空格
startswith("xxx")是否已xxx开头
startswith("e",2,5)2到5组成的字符串是否已e开头
find("x")返回第一个x下标 找不到返回-1
index() 与find功能相同,但找不到会报错
strip()去掉前后空格,也可以去掉换行符中间的不处理
strip("%#@"):包含空格不管前后只要有其中的某个,即删除
lstrip,rstrip 同理
count("z",1,56)返回1-56中z出现的次数
spilt()分割 返回列表 空已包含
format 格式化输出
代码语言:javascript复制s="你是{},今年{},爱好{},我是{}".format("xxx",21,"yy","xxx")
s="你是{0},今年{1},爱好{2},我是{0}".format("xxx",21,"yy")
s="你是{name},今年{age},爱好{like},我是{name}".format(name="xxx",age=21,like="yy")
replace("old","new",count) old->new 替换count次
isdight() 全部是数字
isalpha()全部是字母
isalnum()全部是数字,字母
公共方法
len(str) 返回字符个数,英文,中文都表示个字符
int
bit_length() 转换为2进制最少的位数
列表(有序)32位5亿多个
排序 list.sort(),最快排序 list.sort(reverse=True)倒序 list.reverse()翻转 增删改查 增 list.append(object)增加到最后 无返回值 list.insert(3,object)指定位置插入 list.extend("DZF")最后插入(可迭代的对象:字符串。列表等) ->['D','Z','F'] 删 list.pop(1) 指定删除 有返回值:值 默认删最后一个 list.remove("xx")无返回值 list.clear()清空 del list 删除列表 del list[0:2] 切片删除 改 list[0]=[1,2,3] list[0]="dzf" list[0:2]="xxxx"切片插入都是按照迭代插入即x,x,x,x 查 for i in list: li[0:2]
列表的循环
代码语言:javascript复制列表的嵌套:list = ["dzf","工藤新一",[1,2,3],]
元祖,只读列表,可循环查询,可切片
儿子不能改,孙子可能可以改
zu=(1,2,3,4,[1,2,3,4])
zu不能改,但里边的列表可以改
a.join(可迭代元素x) 返回的是x中的每一个用a隔开:返回连接后字符串,列表的话就是拼接后返回
range 顾头不顾尾
for i in range(0,100):
for i in range(0,100,2)步长2
for i in range(10,0,-1)倒序
字典dict
数据类型:
可变数据类型:list,dict ,set 不可哈希
不可变数据类型:元祖,bool,int,str 可哈希
dict key 必须为不可变数据类型
dict value 任意类型
二分查找,存储关系型数据,好像无序,版本有关
- 增:dict["newKey"]=xxxx
dict.setdefault("xxx")添加"xxx":None
dict.setdefault("xxx","yyy") 若存在xxx的话不做操作
- 改:dict["oldKey"]=xxxx dict1.update(dict2) dict1的所有添加到dict2 有覆盖,无添加
- 删:
dict.pop("key") 返回value
dict.pop("不存在键")报错
dict.pop("不存在键",XXX)不报错,若有删除,若无,返回xxx
dict.popitem():3.6以上默认删除最后一个,3.5版本是随机删除(好像是)
返回的是元祖形势的("key","value")
del dict["key"] #无返回值
del dict["不存在键"]#错误
del dict #delete the dict 打印报错
dict.clear() clear 打印不报错
- 查 dict.keys() 返回的是<class 'dict_keys'> 当做list就行 key列表,list(dict.keys())转换 dict.values() 同上 dict.items()同上 items列表 item是一个key-value元祖 dict可循环默认为key i in dict ==dict.keys() dict.items() ->每个元祖(key,value) 不美观 a,b=1,2 a,b=[1,2] a,b分别为1和2 a,b=[1,2],[1,2]:分别为2个list #一行交换,python专有 a,b=b,a for k,v in dict.items(): print(k,y) dict[key]=value key不存在会报错 dict.get(key,xxx)=value 不存在=None或自定义值 循环 for i in str 循环中改变str实际次数不变 in list 等可变类型 会发生改变 列表循环时可以删除 dict不可以 进阶 "=" 赋值运算,传递内存 == 比较是否相等 is 比较内存 id(obj) 对象的内存 i=6 j=6 id(i)=id(j) #若为300 则不相等与java类似 #数字,字符串小数据池,其他没有小数据池 #数字范围 -5到256 #字符串范围:不知道确切范围,规律: #(不含有特殊字符 则id相同,否则就不同) #str*20 相同 str*21 不同 元祖中只有一个元素t=([1]) 此时t是list类型 t2=([1],) 此时是元祖类型
集合及深浅copy
- 可变的数据类型
- 里边的元素必须不可变
- 无序
- 不重复 set1=set({1,2,3}) set2={1,2,3,4,5,6} #add set1.add("dzf") set.update("abc")->{1,2,3,"a","b","c"} #delete set1.pop() 随机删除,并返回删除的元素 set1.remove("xxxx")按元素删除,若不存在报错 set1.clear() ->set()空集合 del set1 删除整个集合 #update 因为是不可变数据类型,切无序,不能更改 #select for i in set1: pass #顺序变化 #可以求 #交 set1 & set2 set1.intersection(set2) #反交集 set1 ^ set2 set1.symmetric_difference(set2) #并 set1 | set2 set1.union(set2) #差set1独有的 set1-set2 #子集 set1>set2 #当set2是set1子集时返回True 1是2的超集 set1<set2 #1是2的子集 # set1 = set(list) #转换list为set 去重 # s =frozenset(set2) #转化为不可变数据类型,此时s不能更改 文件操作 root,dirs,files = os.walk(path) # file option """ 1,path 2,charset 3,privileges """ # mode = "r" encoding="utf8" utf8是文件建立时的编码方式 # mode = "rb" 不用指定,以文件建立时的方式打开,用以非文字文件 # mode = "w" encoding="utf8" wirte only # mode = "wb" 直接写入byte类型 不用编码方式,f.write("xxxx".encode("utf8")) # mode = "a" encoding = "utf8" 追加方式 # mode = "ab" 追加方式f.write("xxxx".encode("utf8")) # mode = "r " 可读可写(等于追加) 读写是由mode决定光标位置,从光标处开始操作 # mode = "r b" # mode = "w " 先清除后再写,并无意义 # mode = "a " 写 读 # f.seek(0)光标跳转 # 形成文件句柄f f = open("D:/desktop/云空间/profile", mode="r ", encoding="utf8") # content = f.read() # content type 是str类型 自动把utf8转换为unicode 由read()实现 # print(content) # f.close() # if not exist, will create it,if exist will overread it # f = open("log", mode="w", encoding="utf8") # f.write("dzf段志方") # f.read(3) 读取3个字符,一个汉字或一个英文 read读的都是##字符## # f.seek(3) 从第4个开始 按##字节##算,若正好位于中文,会报错 # f.tell() 获取光标位置 # f.readable() 是否可读 # line = f.readline() # 读一行,与java类似 # line = f.readlines() # 以每行为单位 形成列表 # f.truncate(5) 从光标开始截取原文件的5位 abcdef(不确定) # for i in f:print(i) 也可读 # f.close() # 自动关闭,可同时打开多个,推荐使用 # with open("D:/desktop/云空间/profile", mode="r ", encoding="utf8") as obj: # print(obj.read()) # with open("D:/desktop/云空间/profile", mode="r ", encoding="utf8") as obj, # open("D:/desktop/云空间/profile", mode="r ", encoding="utf8") as obj2: # print(obj.read()) # strip() 可以去掉空格或换行符 # 修改文件,文件是不能修改的,只能复制后,删除原来 # delete file rename file import os os.remove("path") os.rename("old","new") 初始函数 # 函数调用时必须已经存在 # def my_len(s): # i = 0 # for k in s: # i = 1 # return None # # # print(my_len('段志方')) # # # def my_len(): # s="as" # i = 0 # for k in s: # i = 1 # return i """ 先定义,后调用 返回值情况, 1,无返回值,如输出就是None 不用写, 只写return (它是结束代码), return None,不常用 2,一个值 int,str,list,dict等 3,多个返回值 return 1,2 多个返回值用多个变量接受,不能多,也不能少 但可以用一个变量接受,按元祖返回 4,解释中输入1,2,3-->(1,2,3) a,b,c=[1,2,3] 可得a=1,b=2,c=3 """ # def func1(a, b = 1): # pass # # # func1((1,2,3)) """ 参数 若多个函数同名,距离调用最近的生效 若无参数,强制传参报错 若有参,不传不报错 1,无参 2,一个参数 3,多个参数def my(a,b): 按顺序传递 也可以 my(b=2,a=1)不报错 可以混用my(1,b=1),先按照位置传,再使用关键字 但my(1,b=1),my(a=1,1)报错,同一变量只能一个值 型参 位置参数:按照位置传递,必须传 默认参数:def my(a,b = 2) 不传及默认,因此默认参数只能在后边,先位置参数 动态参数:def my(*args) 函数中当做元祖,print() my(1,2,3,4.....) 先位置参数,再动态参数(只接受位置传参的),再默认参数,最后**kwargs 动态参数2:def my(**kwargs): 传入dict my(a=1,b=2,c=3)--->{"a":1,"b":2,"c":3} def my(*args,**kwargs) **args 在前,,,必须先位置参数,再关键字 动态参数另一种传参方式 列表或元祖当做位置参数传入 def my(*args): list=(1,2,3) my(*list) 表示按次序传给 def my(**kwargs): dict={"A":1,"B":2} my(**dict) 表示按次序传给 个人感觉这种就是只传一个参数 函数注释 """ # def my(arg): # """ # 功能 # :param arg: # :return: # """ # print(arg) # # # my([1,2,3]) user_list = [ {'username':'barry','password':'1234'}, {'username':'alex','password':'asdf'}, ] board = ['张三','李小四','王二麻子'] while 1: username = input('用户名:') if username.upper() == 'Q':break password = input('密码:') for i in board: if i in username: username = username.replace(i,'*'*len(i)) user_list.append({'username':username,'password':password}) print({'username':username,'password':password}) print(user_list) # 陷阱 # 若默认参数是可变数据类型,调用时,若不传递数据,公用一个资源,字典也类似 def f(a=[]): a.append(1) f() # [1] f() # [1,1] f([]) # [1] f() # [1,1] def f(k,a={}): a[k] = "v" f(1) # {1:"v"} f(2) # {1:"v",2:"v"} f(3) # {1:"v",2:"v",3:"v"}
函数进阶
代码语言:javascript复制# 内置命名空间--解释器
# 解释器启动就可以使用的名字,他们在解释器加载时加载进内存
# 全局命名空间--代码,非函数
# 程序加载时过程中加载的
# 局部命名空间--函数中代码
# 函数内部的名字,调用函数的时候才会产生,调用结束,消失
# 函数名不加括号 ,可打印出内存地址
# 地址 () 相当于执行
# a = 1
# def fun():
# a = 2
# fun()
# print(a) # a=1
# def fun():
# global a # 不推荐使用
# a = 2
# fun()
# print(a) # a=2
# 对于不可变数据类型,在局部可查看全局中的变量
# 但不能直接修改
# 若有修改,在函数中开始时加 global xx
# 若在局部中声明一个global函数,那么此函数在局部内的操作对全局的变量有效
# globals() 永远全局,locals()会变化
# def f():
# x = "111"
# y = "222"
# print(locals()) # 放在本地查看局部中所有变量 字典形式
# print(locals()) # 放在全局,全局就是本地
# print(globals()) # 查看全局的与内置的
# def max(a,b):
# return a if a>b else b # 三目运算符
# 变量 = 条件返回True的结果 if 条件 else 条件返回False的结果
# print(max(1,2))
# 函数嵌套定义
# def f():...
# a = 1
# def outer():
# def inner1():
# a = 2
# def inner2():
# a = 3
# def inner3():
# nonlocal a
# a = 1
# inner3()
# print(a)
# inner2()
# print(a)
# inner1()
# outer()
# print(a)
# 注意 global var 此var必须是全局的,且全局的只有一层,局部可有多层(函数多层嵌套)
# py3 nolocal var 声明了(上层)的(局部变量),局部若没有,会报错
# 函数作为,元素,参数,返回值
# 函数可以赋值 fun = fun1,可变量一样,亦可放在list,dict等作为容器元素
# 打印出来是<function fun_name at 0x0000000>
# 加括号执行 list = [fun,fun2] list[0]()执行,也可作为参数再次传入函数
# def f():
# print(1)
# list = [f]
# list[0]()
# 第一类对象, 函数名就符合
# 运行期创建
# 可作为函数参数或返回值
# 可存入变量的实体
# 闭包:嵌套函数,(内部)调用(外部函)数(变量),若不调用,就是嵌套函数
# def outer():
# a = 1
# def inn():
# print(a)
# print(inn.__closure__) # <cell at addr:int....> 表示是闭包
# outer()
# print(outer.__closure__) # None 不是闭包
# 常用形式, 外部调用函数内部函数,
# 以前不用时,每次outer()内部数据都会建立,
# 此时使用返回值,只要引用存在,数据创建一次,不会随outer结束而消失,避免多次创建
# def outer():
# a = 1
# def inn():
# print(a)
# return inn
# b = outer()
# b()
# import urllib # 模块,py文件
# from urllib.request import urlopen
#
#
# def geturl():
# url = "http://www.xiaohuar.com"
# def get():
# ret = urlopen(url).read()
# return ret
# return get
#
# get = geturl()
# print(get())
# c = fun(10,20) 先执行, 在赋值,赋函数返回值,若无则是None
装饰器
代码语言:javascript复制# 装饰器形成过程
# 装饰器作用
# 不想修改函数的调用方式,但是还要在原始函数中加工能,java中的面向切面编程
# def fun():
# print("原始功能")
# def outer(f):
# def inner():
# print("前置额外功能")
# f()
# print("后置额外功能")
# return inner
# fun = outer(fun)
# fun()
# 被装饰函数可加返回值,需要在inner中接受并返回
# 也可以加参数,inner(*args(1,2,3,4),**kwargs) 接受,此时inner中args是个列表,f(*args,**kwargs) 表示把列表args,按位置传入
# print(*args)--> 1 2 3 4
# 接受聚合,调用打散
# 原则:开放封闭原则
# 对扩展开放,修改封闭
# 语法糖
# @outer @ 装饰器函数名
# def fun():
# print("原始功能")
# 加上语法糖词句(可省)
# fun = outer(fun)
# 装饰器的固定模式(公式)
装饰器进阶
代码语言:javascript复制# 装饰器形成过程
# 装饰器作用
# 不想修改函数的调用方式,但是还要在原始函数中加工能,java中的面向切面编程
# def fun():
# print("原始功能")
# def outer(f):
# def inner():
# print("前置额外功能")
# f()
# print("后置额外功能")
# return inner
# fun = outer(fun)
# fun()
# 被装饰函数可加返回值,需要在inner中接受并返回
# 也可以加参数,inner(*args(1,2,3,4),**kwargs) 接受,此时inner中args是个列表,f(*args,**kwargs) 表示把列表args,按位置传入
# print(*args)--> 1 2 3 4
# 接受聚合,调用打散
# 原则:开放封闭原则
# 对扩展开放,修改封闭
# 语法糖
# @outer @ 装饰器函数名
# def fun():
# print("原始功能")
# 加上语法糖词句(可省)
# fun = outer(fun)
# 装饰器的固定模式(公式)
# def fun():pass
# print(fun.__name__) 打印(执行函数)的字符串函数名,对于装饰器的话,返回的是inner的名字
# print(fun.__doc__) 打印函数注释,同上
# 添加from functools import wraps(固定的) 给inner函数加上@waraps (原始函数名)
# 此时调用fun.___name__ 即可返回原始函数的信息
# 一个装饰器,装饰多个函数,在不同函数上加@语法糖即可
# 带参数的装饰器
# 500个函数要加装饰器,一个函数修饰多个函数
def timmer(f):
def inner(*args, **kwargs):
pass
ret = f(*args, **kwargs)
pass
return ret
return inner
@timmer
def fun(): pass
# 修改,三层装饰器,最多就是三层
FLAG = True
def timmer_out(flag):
def timmer(f):
def inner(*args, **kwargs):
if flag:
pass
ret = f(*args, **kwargs)
pass
else:
ret = f(*args, **kwargs)
return ret
return inner
return timmer
# 加上括号就是调用,先调用再@
# @timmer_out(FLAG) = timmer = timmer_out(FLAG);@timmer
@timmer_out(FLAG)
def fun(): pass
# 多个装饰器装饰一个函数
# 运行时先d1 的前置装饰,d2 的前置装饰,d2的后置装饰,d1的后置装饰
# 两个装饰器,先生效距离原函数近的语法糖,所以先生效的在内部
# 嵌套调用装饰器
def decorate1(f): # f--> fun
def inner1():
pass
def decorate2(f): # f-->inner
def inner2():
pass
@decorate1 # fun = decorate1(fun)->decorate1(inner)==inner2
@decorate2 # fun = decorate2(fun)=inner
def fun():
pass
# 此时调用fun()等于调用inner2
fun()
迭代器与生成器
代码语言:javascript复制# list(generator) 也可以从生成器取值,但是取全部,全部内容内存生成
# def generator():
# print(1)
# yield 1
# print(2)
# g = generator();
# print(g.__next__())
# 调用2次next 第二次会打印2 但会报错
# def generator():
# print(1)
# count = yield 1
# print(2)
# yield 2
# g = generator();
# print(g.__next__()) #执行到 yield 1
# print(g.send()) # send() 与next效果相同
# print(g.send("hello")) # 获取yield 时 传入新的值
# 修改yield 1 为 count = yield 1
# 此时执行到yield 1 时 停止,等待send() ,传入值给上个next,并赋值,在向下执行
# 注意第一次获取生成器时,必须使用next,
# 最后一个yield 不能接受外部的值,最后一个yield会后不能有代码,若必须使用,最后加yield 即可, 空
# 获取移动平均值
# def average():
# sum = 0
# count = 0
# avg = 0
# while 1:
# num = yield avg
# sum = num
# count =1
# avg = sum / count
# avg = average()
# print(avg.__next__())
# print(avg.send(10))
# print(avg.send(20))
# def generator():
# a = "abcd"
# b = "1234"
# # for 循环yield a
# yield from a
# yield from b
# for i in generator():
# print(i) # a b c d 1 2 3 4
#
# 生成器表达式和列表推导式
# 推导式
# list = [i for i in range(10)]
# print(list)
# list = ["dzf%s" %i for i in range(10)]
# print(list)
# 其他推导式
# [元素或操作 for 元素 in 可迭代数据类型] 遍历后处理
# [满足条件的元素的操作 for 元素 in 可迭代数据类型 if 元素条件] 筛选功能
# 列表推导式
# [i for i in range(30) if i%3==0] -->[0,3,6....]
# 双层for 查找 双层list中数据
# names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
# ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
# [name for list in names for name in list if name.count('e')==2]
# 集合推导式,
# {x**2 for x in [1,-1,2]} -->{1,4} 自带去重
# [x**2 for x in [1,-1,2]] -->[1,1,4]
# 字典推导式
# 调换字典的key-value
# dict = {"a":1,"b":2,"A":7,"B":45}
# dict2 = {dict[k]:k for k in dict}
# 合并大小写对应的value值,将k统一成小写
# dict3 = {k.lower(): dict.get(k.lower(),0) dict.get(k.upper(), 0) for k in dict}
# print(dict3)
# 表达式,括号不同,g为生成器.
# g = (i for i in range(10))
# print(g)
# for i in g:
# print(i)
# print(type(list()))
# print(type({1,2,34,5,5,5,}))
# 作业
# def find(path):
# with open(path,encoding="utf-8") as f:
# for line in f:
# if "xxx" in line:
# yield line
# for line in find("xxx"):
# print(line)
# 生成器面试题
# def demo():
# for i in range(4):
# yield i
# g = demo()
# g1 = (i for i in g) # -->此时未for循环,只生成生成器
# def fun():
# for i in g:
# yield i
# g2 = (i for i in g1)
# print(list(g1)) # -->[1,2,3,4],g1,执行生成器,全部取出
# print(list(g2)) # -->[],此时从g1取值没有了,为空
# 2
def add(n,i):
return n i
def test():
for i in range(4):
yield i
g=test()
for n in [1,10,5]:
g = (add(n,i) for i in g)
#
# n = 1
# g=(add(n,i) for i in g)
# n = 10
# g=(add(n,i) for i in g) # -->g=(add(n,i) for i in (add(n,i) for i in g))
print(list(g))
代码语言:javascript复制list1 = [ # 列表剥皮
1,
2,
[
3,
4,
[5,6,7]
],
[
3,
4,
[
5,
6,
7,
[8,9,10]
]
]
]
def f3(x): # 生成器
return [a for b in x for a in f3(b)] if isinstance(x, list) else [x]
def f2(x):
l = []
for i in x:
if isinstance(i,list):
for k in f2(i):
l.append(k)
else:
l.append(i)
return l
def f(x,l=[]):
for i in x:
if isinstance(i,list):
f(i)
else:
l.append(i)
return l
print(f(list1))
print(f2(list1))
print(f3(list1))
内置函数
https://www.processon.com/view/link/5d4fa21be4b0ac2b61744998
https://img.yuanmabao.com/zijie/pic/2020/05/08/g0nint0djnf
代码语言:javascript复制# 内置函数
# callable('xxx') # 检测是不是函数--->True or False
# help(str) # 显示str的帮助信息
# (导入)import time=time = __import__('time')
# print(time.time())
# f=open()
# f.read()
# print(f.writable()) # 检测是否可写
# print(f.readable()) # 检测是否可读
# # 内存相关
# id()
# hash(),一次执行中,相同的对象hash值不变,不管对象多大,hash值有范围
# print(hash(123456))
# print(hash('123456'))
# print(hash([1,2,3,4,5,6])) # 不可hash
# print(hash((1,2,3,4,5,6)))
# print()
# print("xxxx") # 自带换行符
# print("xxx",end='') # 取消换行
# print("xxx",sep='|') # 指定分隔符
# f = open('file','w') # 指定打印文件位置,控制台也是文件
# print("xxx",file=f)
# f.close()
# 进度条
# r 表示回到行首
# n 使最后换行
# flush=True, 传入字符立即写入,不缓存再写
# import time
# for i in range(0,101,2):
# time.sleep(0.1)
# char_num = i//2
# per_str="r%s%%:%sn" % (i,'*'*char_num) if i==100 else "r%s%%:%s" % (i,'*'*char_num)
# print(per_str,end='',flush=True)
# exec eval, 都可执行字符串代码,exec 无返回值
# eval 只能用明确知道的要执行的代码,不常用
# eval -- 有结果的简单计算
# exec -- 简单流程控制
# exec('print(123)') # 123
# eval('print(123)') # 123
# print(eval('1 2 3 4')) # 10
# print(exec('1 2 3 4')) # None
# compile 把代码编译为字节码,下次调用节省时间,
# code1 = 'for i in range(0,10):print(i)'
# # '' 为文件名,没有的话置空
# compile1 = compile(code1,'','exec')
# code2 = '1 2 3 4'
# compile2 = compile(code2,'','eval')
# print(eval(compile2))
# code3 = 'name = input("please input your name:")'
# compile3 = compile(code3,'','single')
# # name 执行前name不存在
# exec(compile3) # 执行后有name,虽然报错,但存在
# print(name)
# complex 复数 ,实部,虚部都是float
# print(complex(12,3)) # -->12 3j
"""
实数
有理数:小数,有限循环小数
无理数:无线不循环小数
虚数:x的平方式负数,i**2 = -1
复数:实数 虚数,5 ni ,不能比较大小,
"""
# 浮点数
# print(float(12))
"""
354.123 = 3.45123*10**2=35.4123*10,点回浮动 所以叫浮点数
float:有限循环,无限循环,
不是float:无线不循环
"""
# 进制转换 bin() 0b, oct() 0o,hex() 0x
# abs(n) 绝对值
# divmod(x,y) -->(n,m) x/y 商n余m,print(divmod(8,2))
# round(3.456879,2) 精确值,会四舍五入
# pow(x,y) 幂运算 pow(x,y,z) x**y % z 幂运算后取余
# sum(可迭代,切里边是数字)
# print(sum([1,2,3,4])) 基础值为0 ->10
# print(sum([1,2,3,4],10)) 基础值为10 -> 20
# min() 最小值,可传迭代,也可*args
# min([1,2,3,4])
# min(1,2,3,4)
# min(1,2,3,-4,key=abs) 可以 把key 用方法计算后求函数值
# max同min 注意,返回的是参数值,不是进过处理后的值
# reversed(list) #不改变原来列表,返回一个迭代器
# l=slice(1,5,2) 切片规则
# list[l]
# formate(数字)->转字符串
# formate('test','<20') 20空间 左对齐
# formate('test','>20') 右对齐
# formate('test','^20') 居中
# 等
# bytes 转换bytes类型
# 拿到gbk 转unicode 再转到utf8
# str = bytes("你好",encoding="gbk") # unicode转gbk的bytes类型
# str.decode("gbk") # 你好
# str = bytes("你好",encoding="utf8") # unicode转utf8的bytes类型
# str.decode("utf8") # 你好
# bytearray("你好",encoding="utf8") 返回byte 列表,修改里边的16进制可实现更改
# ord('a')查看编码 按照unicode
# print(ord('段'))
# print(chr(97))
# ascii('xxx')
# %s,%r
# print(repr('1')) # --> '1'
# print(repr(1)) # --> 1
# 枚举 l = [1,2,3,4] enum = enumerate(l)
# all([]) 判断里边字符是否全为True
# print(all([1,2,3,0]))
# any() 看上边
# zip()
"""
l = [1,2,3]
l2 = ["a","b","c"]
for i in zip(l,l2) 两边数可不同,开可以加l3,l4,若为字典(注意无序),只能加上key
print(i) -->(1,'a') (2,'b') (3,'c')
"""
# filter(),返回handler处理后的结果,bool
# 等于[i for i in [1,2,3,4,5] if i%2==1]
# ret = filter(handler,可迭代的元素) ret是迭代器
# def fun(x):
# return x%2==1
# ref = filter(fun,[1,2,3,4,5,6])
# print(list(ref)) --> [1,3,5]
# import math
# print(math.sqrt(9))
# print(1.5%1)
# map(fun,可迭代元素) 分处理后,返回可迭代元素
# ret = map(abs,[1,-4,-8])
# sorted(可迭代元素,key=fun,reserve=True) 自定义排序,返回新列表,元数据不变
# l.sort(key=abs) 按绝对值排序
匿名函数
代码语言:javascript复制# 匿名函数
# 必须在一行,
# lamdba 定义,n,m参数,冒号后边直接是返回值
calc = lambda n,m:m*n 2
# 调用,还可以有名字, 匿名的时候对于函数名做参数时使用
# max([],key=lambda k:xxx)
# max,min,sorted,filter,map
print(calc(1,2))
# 面试题
#现有两元组(('a'),('b')),(('c'),('d')),
# 请使用python中匿名函数生成列表[{'a':'c'},{'b':'d'}]
# ret = zip((('a'),('b')),(('c'),('d')))
# ret = map(lambda t:{t[0]:t[1]},ret)
# print(list(ret))
# max min sorted filter map
# 匿名函数 == 内置函数
# zip
# ret = zip((('a'),('b')),(('c'),('d')))
# res = map(lambda tup:{tup[0]:tup[1]},ret)
# print(list(res))
# 下面代码的输出结果是什么?
# def multipliers():
# return [lambda x:i*x for i in range(4)] # 返回4个lambda ,但最后i最后都是3
# print([m(2) for m in multipliers()]) [6,6,6,6]
# return (lambda x:i*x for i in range(4)) 生成器,
# --->[0,2,4,6]
# 作业
# 3.用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb
name=['alex','wupeiqi','yuanhao','nezha']
# def func(item):
# return item '_sb'
# ret = map(func,name) #ret是迭代器
# for i in ret:
# print(i)
# print(list(ret))
# ret = map(lambda item:item '_sb',name)
# print(list(ret))
# 4.用filter函数处理数字列表,将列表中所有的偶数筛选出来
# num = [1,3,5,6,7,8]
# def func(x):
# if x%2 == 0:
# return True
# ret = filter(func,num) #ret是迭代器
# print(list(ret))
#
# ret = filter(lambda x:x%2 == 0,num)
# ret = filter(lambda x:True if x%2 == 0 else False,num)
# print(list(ret))
# 5.随意写一个20行以上的文件
# 运行程序,先将内容读到内存中,用列表存储。
# 接收用户输入页码,每页5条,仅输出当页的内容
# with open('file',encoding='utf-8') as f:
# l = f.readlines()
# page_num = int(input('请输入页码 : '))
# pages,mod = divmod(len(l),5) #求有多少页,有没有剩余的行数
# if mod: # 如果有剩余的行数,那么页数加一
# pages = 1 # 一共有多少页
# if page_num > pages or page_num <= 0: #用户输入的页数大于总数或者小于等于0
# print('输入有误')
# elif page_num == pages and mod !=0: #如果用户输入的页码是最后一页,且之前有过剩余行数
# for i in range(mod):
# print(l[(page_num-1)*5 i].strip()) #只输出这一页上剩余的行
# else:
# for i in range(5):
# print(l[(page_num-1)*5 i].strip()) #输出5行
# 6.如下,每个小字典的name对应股票名字,shares对应多少股,price对应股票的价格
# portfolio = [
# {'name': 'IBM', 'shares': 100, 'price': 91.1},
# {'name': 'AAPL', 'shares': 50, 'price': 543.22},
# {'name': 'FB', 'shares': 200, 'price': 21.09},
# {'name': 'HPQ', 'shares': 35, 'price': 31.75},
# {'name': 'YHOO', 'shares': 45, 'price': 16.35},
# {'name': 'ACME', 'shares': 75, 'price': 115.65}
# ]
# 6.1.计算购买每支股票的总价
# ret = map(lambda dic : {dic['name']:round(dic['shares']*dic['price'],2)},portfolio)
# print(list(ret))
# 6.2.用filter过滤出,单价大于100的股票有哪些
# ret = filter(lambda dic:True if dic['price'] > 100 else False,portfolio)
# print(list(ret))
# ret = filter(lambda dic:dic['price'] > 100,portfolio)
# print(list(ret))
# 每周大作业
# 这一周写得所有博客地址,精确到页的url,至少三篇,内容不限
# 大作业 : py readme(对作业描述,顺便可以写点儿你想和导员沟通的) 流程图
#
初识递归
代码语言:javascript复制# 初识递归 最大深度1000左右 997 或998
# 设置默认次数
# import sys
# sys.setrecursionlimit(100)
# 若递归次数太多,则不适合递归
# 二分查找算法 必须处理有序的列表
# l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
# 5000000 4999998
# 代码实现
# def find(l,aim):
# mid_index = len(l) // 2
# if l[mid_index] < aim:
# new_l = l[mid_index 1 :] 每次传入新列表,最终查到时下标不对
# find(new_l,aim)
# elif l[mid_index] > aim:
# new_l = l[:mid_index]
# find(new_l, aim)
# else:
# print('找到了',mid_index,l[mid_index])
#
# find(l,66)
l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
# def find(l,aim,start = 0,end = None):
# end = len(l) if end is None else end # end = len(l) 24
# mid_index = (end - start)//2 start #计算中间值 12 0 = 12
# if l[mid_index] < aim: #l[12] < 44 #41 < 44
# find(l,aim,start =mid_index 1,end=end) # find(l,44,start=13,end=24)
# elif l[mid_index] > aim:
# find(l, aim, start=start, end=mid_index-1)
# else:
# print('找到了',mid_index,aim)
#
# def find(l,aim,start = 0,end = None): # l,44,start=13,end=24
# end = len(l) if end is None else end # end = 24
# mid_index = (end - start)//2 start #计算中间值 24-13/2 = 5 13 = 18
# if l[mid_index] < aim: #l[18] < 44 #67 < 44
# find(l,aim,start =mid_index 1,end=end)
# elif l[mid_index] > aim: # 67 > 44
# find(l, aim, start=start, end=mid_index-1) # find(l,44,start=13,end=17)
# else:
# print('找到了',mid_index,aim)
#
# def find(l,aim,start = 0,end = None): # l,44,start=13,end=17
# end = len(l) if end is None else end # end = 17
# mid_index = (end - start)//2 start #计算中间值 17-13/2 = 2 13 = 15
# if l[mid_index] < aim: #l[15] < 44 #55 < 44
# find(l,aim,start =mid_index 1,end=end)
# elif l[mid_index] > aim: # 55 > 44
# find(l, aim, start=start, end=mid_index-1) # find(l,44,start=13,end=14)
# else:
# print('找到了',mid_index,aim)
#
# def find(l,aim,start = 0,end = None): # l,44,start=13,end=14
# end = len(l) if end is None else end # end = 14
# mid_index = (end - start)//2 start #计算中间值 14-13/2 = 0 13 = 13
# if l[mid_index] < aim: #l[13] < 44 #42 < 44
# find(l,aim,start =mid_index 1,end=end) # find(l,44,start=14,end=14)
# elif l[mid_index] > aim: # 42 > 44
# find(l, aim, start=start, end=mid_index-1)
# else:
# print('找到了',mid_index,aim)
def find(l,aim,start = 0,end = None):
end = len(l) if end is None else end
mid_index = (end - start)//2 start
if start <= end:
if l[mid_index] < aim:
return find(l,aim,start =mid_index 1,end=end)
elif l[mid_index] > aim:
return find(l, aim, start=start, end=mid_index-1)
else:
return mid_index
else:
return '找不到这个值'
ret= find(l,44)
print(ret)
# 参数 end
# 返回值
# 找不到的话怎么办
# l.index()
# 67 发生两次调用
# 66 发生好几次
# 44 找不到
# age,二分查找,三级菜单的代码看一遍
# 斐波那契 # 问第n个斐波那契数是多少
# 阶乘
#3! 3*2*1
# 附加题 :考试附加题
# 递归实现
# l = [1,2,3]
# print(l[1:1])
# 超过最大递归限制的报错
# 只要写递归函数,必须要有结束条件。
# 返回值
# 不要只看到return就认为已经返回了。要看返回操作是在递归到第几层的时候发生的,然后返回给了谁。
# 如果不是返回给最外层函数,调用者就接收不到。
# 需要再分析,看如何把结果返回回来。
# 循环
# 递归
# 斐波那契 # 问第n个斐波那契数是多少
# 1,1,2,3,5,8 #fib(6) = fib(5) fib(4)
# def fib(n):
# if n == 1 or n==2:
# return 1
# return fib(n-1) fib(n-2) #两次递归非常慢
# print(fib(50))
# fib(6) = fib(5) fib(4)
# fib(5) = fib(4) fib(3)
# fib(4) = fib(3) fib(2)
# fib(3) = fib(2) fib(1)
# fib(2) = 1
# fib(1) = 1
# def fib(n,l = [0]):
# l[0] =1
# if n ==1 or n == 2:
# l[0] -= 1
# return 1,1
# else:
# a,b = fib(n-1)
# l[0] -= 1
# if l[0] == 0:
# return a b
# return b,a b
# print(fib(50))
# 没看懂
def fib(n,a=1,b=1):
if n==1 : return a
return fib(n-1,b,a b)
print(fib(50))
# 阶乘
#3! 3*2*1
# 2! 2*1
# 1! 1
# def fac(n):
# if n == 1 :
# return 1
# return n * fac(n-1)
#
# print(fac(100))
# 附加题 :考试附加题
# 递归实现
模块
代码语言:javascript复制# 模块的导入
# 导入的时候会执行里面的语句,有print()也会输出,多次导入只调用一次
"""
需求模块:本模块测试,print()会执行,其他文件调用,print()等不执行
__name__:本模块名字,单若在某个模块中开始运行的,输出是__main__,否则就是文件名
解决方法
被调用模块中:
def func():
pass
if __name__ == '__main__'
fun()
"""
# import xxxx # 找到模块,读内容到专属命名空间
# xxxx.func() xxxx.var
# 已经导入的modules字典,所以不会重复导入 名字:路径
# import sys
# print(sys.modules)
# import time as t 给模块起别名,提高兼容性
# import time, sys, os 同时引入多个代码,但不推荐
# 先导内置,扩展django,自己的
# from demo import func,var 都可以
# from demo import func as t
# from time import * 不安全
# 被调用的模块第一行加入 __all__ = ['var','fun']
# 其他文件用 *导入 该模块时 只能使用 list中含有的量
正则模块
代码语言:javascript复制#正则模块
"""
. 换行外任意字符
w 数字字母下划线
s 任意空白字符
d 数字
# 上边3个大写就是非,任意两对就是匹配全局
n 换行
t 制表
b 匹配单词结尾,用得少,前边加些字符,不然不显示
^x 以x开头,只匹配一个
() 一个组
[^ab] ab都不匹配 ,非
以上都是单个字符匹配
* ? 等 只约束 前面的一个规则,若有每个,都加 即可
d* 多次匹配,空也可匹配
d 匹配一次或多次
d? 匹配一次
{n} 匹配n次
{n,m} n到m次
()? ()中只出现一次
.*?x 前边任意长度,直到出现x结束
转义符匹配
正则中\n 匹配n
语言中\\n 匹配n 为每个""转义
或r'\n' 匹配n 取消""的转义功能
"""
# re模块
import re
# match (从头)开始匹配,匹配上就返回一个变量,search即时在中间也可以查到
# group显示
# 没有匹配返回Nnoe,调用group出错
ret = re.match('[a-z] ',"123 dzf gyg lzt")
print(ret)
# findall 匹配所有符合的放在列表中
ret = re.findall("[a-z] ","dzf gyg lzt")
print(ret)
# search,找到第一个就返回,返回一个对象,ret.group()回去值
# 若找不到返回None,使用group()则会报错
ret = re.search("[a-z] ","123 dzf gyg lzt")
print(ret.group())
# 分割,先按照a,分割再按b分割
re.split("[ab]","abcd")
# 替换所有数字为H,若没有1 表示匹配一次
re.sub('d',"H","cacasccass366asdas",1)
# 返回替换后的结果 并返回次数 元祖("str",次数)
re.subn('d',"H","cacasccass366asdas",1)
# 编译正则表达式
re.compile('d{3}') # 供后使用
# 返回一个存放结果的迭代器
ret = re.finditer("d","huoiuhizai23nusdwhjj")
#查看
next(ret).group() # 查看第一个
next(ret).group() # 查看第二个
for i in ret: #第3个开始
i.group()
# 对于search group() 返回一个完整的匹配
# group(1) group(2) 返回其中的一部分
# ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
# print(ret) # ['oldboy'] 这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
# 保留分组优先
# ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
# print(ret) # ['www.oldboy.com']
ret=re.split("d ","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']
ret=re.split("(d )","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']
#re.findall(x,xx,flag)
# flag = rs.I 或略大小写
# flag = rs.M 多行模式,改变^$的行为
# flag = rs.S 点可以匹配换行,以及任意字符
# flag = rs.L 做本地化识别的匹配,表示特殊字符集 s,w 等,不推荐
# flag = rs.U 使用w w等,使用取决于unicode定义的字符属性,pythons默认使用
# flag = rs.X 冗长模式,pattern可以是多行,忽略空白字符,可添加注释
正则模块2
代码语言:javascript复制# 正则表达式
# 字符组 [字符]
# 元字符
# w d s
# W D S
# . 除了换行符以外的任意字符
# n t
# b
# ^ $ 匹配字符串的开始和结束
# () 分组 是对多个字符组整体量词约束的时候用的
#re模块:分组是有优先的
# findall
# split
# | 从左到右匹配,只要匹配上就不继续匹配了。所以应该把长的放前面
# [^] 除了字符组内的其他都匹配
# 量词
# * 0~
# 1~
# ? 0~1
# {n} n
# {n,} n~
# {n,m} n~m
# 转义的问题
# import re
# re.findall(r'\s',r's')
# 惰性匹配
# 量词后面加问号
# .*?abc 一直取遇到abc就停
# re模块
# import re
# re.findall('d','awir17948jsdc',re.S)
# 返回值:列表 列表中是所有匹配到的项
# ret = search('d(w) ','awir17948jsdc')
# ret = search('d(?P<name>w) ','awir17948jsdc')
# 找整个字符串,遇到匹配上的就返回,遇不到就None
# 如果有返回值ret.group()就可以取到值
# 取分组中的内容 : ret.group(1) / ret.group('name')
# match
# 从头开始匹配,匹配上了就返回,匹配不上就是None
# 如果匹配上了 .group取值
# 分割 split
# 替换 sub 和 subn
# finditer 返回迭代器
# compile 编译 :正则表达式很长且要多次使用
import re
# ret = re.search("<(?P<tag_name>w )>w </(?P=tag_name)>","<h1>hello</h1>")
# #还可以在分组中利用?<name>的形式给分组起名字
# #获取的匹配结果可以直接用group('名字')拿到对应的值
# print(ret.group('tag_name')) #结果 :h1
# print(ret.group()) #结果 :<h1>hello</h1>
# ret = re.search(r"<(w )>w </1>","<h1>hello</h1>")
# #如果不给组起名字,也可以用序号来找到对应的组,表示要找的内容和前面的组内容一致
# #获取的匹配结果可以直接用group(序号)拿到对应的值
# print(ret.group(1))
# print(ret.group()) #结果 :<h1>hello</h1>
import re
# ret=re.findall(r"d .d |(d )","1-2*(60 (-40.35/5)-(-4*3))")
# print(ret) #['1', '2', '60', '40', '35', '5', '4', '3']
# ret.remove('')
# print(ret)
# ret=re.findall(r"-?d .d*|(-?d )","1-2*(60 (-40.35/5)-(-4*3))")
# print(ret) #['1', '-2', '60', '', '5', '-4', '3']
# ret.remove("")
# print(ret) #['1', '-2', '60', '5', '-4', '3']
# 首先得到一个字符串
# 去空格
# 没有空格的字符串
# 先算最里层括号里的 : 找括号 ,且括号里没有其他括号
# 得到了一个没有括号的表达式 :只有加减乘除 从左到右先找到第一个乘除法 —— 重复
# 所有的乘除法都做完了
# 计算加减 —— 加减法
# 只有一个数了 就可以结束了
collection
代码语言:javascript复制# collections 扩展数据类型
# 时间模块
# random 随机数模块
# os 操作系统
# sys 与python解释器有关
# 序列化模块 数据类型与str的转换
# collections
"""
namedtuple:
deque:双端队列
counter:计数器
orderedDict:有序字典
defaultdict:带默认值的字典
"""
# 列表,字典,字符串,集合,frozenset,字符串,堆栈
# namedtuple 可用名字获取值,
# from collections import namedtuple
# Point = namedtuple("point",['x','y','z'])
# p = Point(1,2,3)
# p2 = Point(1,2,3)
# print(p.x) # 1
# print(p.y) # 2
# print(p.z) # 3
# print(p) # (x=1,y=2)
# 花色与数字
# Card = namedtuple("card",["suits","number"])
# c1 = Card("红桃",2)
# print(c1)
# queue 队列,内容不可看
# import queue
# q = queue.Queue() # q不可for,不可放多个值,但可放其他元素类型
# q.put(10)
# q.put(10)
# q.put(10)
# q.put(10)
# print(q.get())
# print(q.get())
# print(q.get()) # 取内容时,若没有了,阻塞,等待再次添加,继续
# print(q.qsize()) # 查看剩余的,
# deque 双端队列,两端都可以存取
# from collections import deque
# dq = deque([1,2])
# dq.append('a') # 从后边放数据[1,2,'a']
# dq.appendleft('b') # 从前边放数据['b',1,2,'a']
# dq.insert(2,3) # ['b',1,3,2,'a']
# print(dq.pop()) # 从后边取数据 a
# print(dq.popleft()) # 从前边取数据 b
# print(dq) # deque([1, 3, 2]) 可看内容
# 有序字典
# from collections import OrderedDict
# 初始化时要如下定义,列表型定义,所以有序
# od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
# print(od) # -->OrderedDict([('a', 1), ('b', 2), ('c', 3)])
# OrderedDict的Key是有序的
# print(od['a']) # 仍可这样访问
# for k in od:
# print(k)
# defaultdict
# from collections import defaultdict
# d = defaultdict(lambda: 5) # value 默认是5
# print(d['k'])
# d = defaultdict(list) # 使字典的value默认为list,其他元素也可
# d['k'].append(1)
# print(d)
# from collections import Counter
# c = Counter("asdaquidbqu9fu9qnnaibcba")
# print(c) # Counter({'a': 4, 'q': 3, 'u': 3, 'b': 3, 'd': 2, 'i': 2, '9': 2, 'n': 2, 's': 1, 'f': 1, 'c': 1})
time
思考题,时间相减
代码语言:javascript复制import time
# time.sleep(100) # stop100 second
# time.time() # 返回s为单位的浮点数
# 格式化时间 —— 字符串: 给人看的 string str
# 时间戳时间 —— float时间 : 计算机看的 timestamp
# 结构化时间 —— 元祖 :计算用的 struct_time
# %a 简称英文星期
# %A 全称英文星期
# print(time.strftime("%Y-%m-%d %a %H:%M:%S")) #year month day HOUR MINUTE SECOND
# print(time.strftime("%Y/%m/%d %H:%M:%S")) #year month day HOUR MINUTE SECOND
# print(time.strftime("%m-%d %H:%M:%S")) #year month day HOUR MINUTE SECOND
# print(time.strftime("%H:%M:%S")) #year month day HOUR MINUTE SECOND
# print(time.strftime("%H:%M")) #year month day HOUR MINUTE SECOND
# struct_time = time.localtime()
# print(struct_time)
# print(struct_time.tm_year)
# 时间戳和结构化时间
# t = time.time()
# print(t)
# print(time.localtime(3000000000)) # 结构北京时间
# print(time.gmtime(t)) # 结构 格林威治时间
# print(time.mktime(time.localtime())) # 时间戳
# print(time.strptime('2000-12.31','%Y-%m.%d')) # 转为结构化时间
# print(time.strftime('%m/%d/%Y %H:%M:%S',time.localtime(3000000000))) # 结构化转格式化
# print(time.asctime()) # asc串
# print(time.asctime(结构化)) # 转asc
# print(time.ctime(时间戳)) # 转asc
# 思考题:两个时间相减,显示差了几年,几月,几天
# 张天福 —— 中国茶叶之父
# 陈味聪
# 周天霖
# 绿茶 : 龙井 碧螺春 竹叶青 信阳毛尖 六安瓜片 太平猴魁 安吉白茶
# 白茶 : 福鼎白茶 银针(100%芽) 白牡丹(一芽一叶) 贡眉(一芽两叶) 寿眉(一芽三叶)
# 黄茶 : 黄山毛峰 霍山黄芽
random
代码语言:javascript复制import random
random.random() # 大于0小于1
random.uniform(1,3) # 大于1 小于3
random.randint(1,5) # 大于等于1 小于等于5
random.randrange(1,10,2) # 大于等于1 小于10 之间的奇数
random.choice([1,'23',[4,5]]) # 1或'23'或[4,5] 任意一个
random.sample([1,'23',[4,5]],2) # 任意两个组合 [[4,5],'23']
os
root,dirs,files in os.walk(path) 返回的是生成器
第一条,root = path,dir= path里边的第一级目录,files为第一级文件,
第二次循环,root为path的上一个循环中root中的第一个
依次循环
和使用os.walk(path).__next()__获取第一次记录
代码语言:javascript复制import os
os.getcwd() # 获取当前路径
os.chdir(r"xxxx") # 改变当前脚本执行路径,再次getcwd()会变化
os.curdir() # "."
os.pardir() # ".."
# os.chdir("..") = os.chdir(os.pardir())
os.makedirs("xxx/yyy") # 新建文件夹,级联
os.removedirs("目录") # 删除后,到上一级,为空就继续删除
os.mkdir("xxx") # 单级目录
os.rmdir("xxx") # 单级空目录
os.listdir("xxx")
os.remove("xxx") # 删除文件
os.rename("old","new") #
os.stat("path/file") # 获取文件/目录信息 ,大小,修改时间等
os.sep # 路径分隔符 win \ linux / 跨平台使用
os.linesep # 当前终止符 win tn linux n
os.pathsep # 路径文件分隔符 win ; linux :
os.name # 字符串指示当前使用的平台 win nt; linux posix
os.system("bash command") # 不用打印直接输出,但无返回值
os.popen("bash command").read() # 获取执行结果,
os.environ # 环境变量
os.path
os.path.abspath("path") # 返回path绝对路径
os.path.split("path") # 返回目录与文件名,元祖返回
os.path.dirname("path") # 返回path目录,不包括文件
os.path.basename("path") # 返回最后的文件名,若/ 结尾返回空
os.path.exists("path") #True Flase
os.path.isabs("path") # 是否是绝对路径
os.path.isfile("path")
os.path.isdir("path") # 是否存在(目录)
print(os.path.join("xxx","yyy","zzz")) # 拼接为 xxxyyyzzz,
os.path.getatime("path") # 最后访问时间
os.path.getmtime("path") # 最后修改时间
os.path.getsize("path") # 大小
sys
代码语言:javascript复制import sys
sys.platform # 返回操作系统位数
sys.version # 返回python版本
sys.exit() # 程序退出 0 正常退出,非0 不正常
sys.path # 所有搜索模块的路径,list,当前路径,python默认包路径等...
sys.path.clear() # 清空后 import os 无效
sys.argv # python xxx.py a b c ;
# 用于接收 a b c 等参数 list
# 不用input,节省时间
序列化模块
代码语言:javascript复制'abdsafaslhiewhldvjlmvlvk['
# 序列化 —— 转向一个字符串数据类型
# 序列 —— 字符串
"{'k':'v'}"
# 数据存储
# 网络上传输的时候
# 从数据类型 --> 字符串的过程 序列化
# 从字符串 --> 数据类型的过程 反序列化
# json ***** 非常重要
# pickle ****
# shelve *** python3 新出现的
# json # 数字 字符串 列表 字典 元组(转为list),反序列后还是list
# 通用的序列化格式
# 只有很少的一部分数据类型能够通过json转化成字符串
# 只有json,方式文件中的可读
# pickle
# (所有的python中的数据类型)都可以转化成字符串形式
# pickle序列化的内容(只有python能理解)
# 且部分反序列化依赖python代码
# shelve
# 序列化句柄
# 使用句柄直接操作,非常方便
# json dumps序列化方法 loads反序列化方法 内存数据
# dic = {1:"a",2:'b'}
# print(type(dic),dic) # <class 'dict'> {1:"a",2:'b'}
# import json
# str_d = json.dumps(dic) # 序列化
# print(type(str_d),str_d) # <class 'str'> {1:"a",2:'b'}
# # '{"kkk":"v"}' 字符串元素全部双引号显示
# dic_d = json.loads(str_d) # 反序列化
# print(type(dic_d),dic_d)
import json
# json (dump) load 文件数据
# dic = {1:"a",2:'b'}
# f = open('fff','w',encoding='utf-8')
# json.dump(dic,f)
# f.close()
# f = open('fff') # 没中文可不用写编码
# res = json.load(f)
# f.close()
# print(type(res),res)
import json
# json dump load
# dic = {1:"中国",2:'b'}
# f = open('fff','w',encoding='utf-8')
# json.dump(dic,f,ensure_ascii=False) # 默认以bytes写入,改为false时可以写中文
# json.dump(dic,f,ensure_ascii=False)
# 可以两次写
# f.close()
# f = open('fff',encoding='utf-8')
# res1 = json.load(f)
# res2 = json.load(f)
# f.close()
# print(type(res1),res1)
# print(type(res2),res2)
# 一次读会报错
# json
# dumps {} -- > '{}n'
# 一行一行的读
# '{}n' 读出来一行
# '{}' loads 队一行loads
# 例 逐行写入
# l = [{'k':'111'},{'k2':'111'},{'k3':'111'}]
# f = open('file','w')
# import json
# for dic in l:
# str_dic = json.dumps(dic)
# f.write(str_dic 'n')
# f.close()
# 读
# f = open('file')
# import json
# l = []
# for line in f:
# dic = json.loads(line.strip())
# l.append(dic)
# f.close()
# print(l) # 转回list
import pickle #
# dic = {'k1':'v1','k2':'v2','k3':'v3'}
# str_dic = pickle.dumps(dic)
# print(str_dic) #一串二进制内容
#
# dic2 = pickle.loads(str_dic)
# print(dic2) #字典
# import time 文件操作时用rb,wb,(可以分部调用)
# struct_time1 = time.localtime(1000000000)
# struct_time2 = time.localtime(2000000000)
# f = open('pickle_file','wb')
# pickle.dump(struct_time1,f)
# pickle.dump(struct_time2,f)
# f.close()
# f = open('pickle_file','rb')
# struct_time1 = pickle.load(f)
# struct_time2 = pickle.load(f)
# print(struct_time1.tm_year)
# print(struct_time2.tm_year)
# f.close()
# =======================================
# 会产生三个临时文件,且不支持多个应用同时写
# import shelve
# f = shelve.open('shelve_file')
# f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接对文件句柄操作,就可以存入数据
# f.close()
#
# import shelve
# f1 = shelve.open('shelve_file')
# existing = f1['key'] #取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错
# f1.close()
# print(existing)
# ======================================
# 只读方式打开,本应该不能够修改,但有时候却可以修改
# import shelve
# f = shelve.open('shelve_file', flag='r')
# existing = f['key']
# print(existing) 原来内容
# f.close()
#
# f = shelve.open('shelve_file', flag='r')
# existing2 = f['key'] 修改
# f.close()
# print(existing2) 再次打印
# ============================================
# 修改不生效
import shelve
# f1 = shelve.open('shelve_file')
# print(f1['key'])
# f1['key']['new_value'] = 'this was not here before'
# f1.close()
# writeback = True 生效, 会消耗内存, 一般都是重新建文件,写入,重命名
f2 = shelve.open('shelve_file', writeback=True)
print(f2['key'])
# f2['key']['new_value'] = 'this was not here before'
f2.close()
# ============================================
包
代码语言:javascript复制# 把解决一类问题的模块放在同一个文件夹里 —— 包'
# import xx.yy.zz 点的左边必须是包
# from xx.yy import zz
# from xx import yy.zz 错误
# 例: 包1/包2/包3/文件
# import 包1
# 包1.包2.包3.文件.fun() 会出错
# import package 会自动执行包下__init__py文件
# from 包1 import 包2 # 包1 下init
# from 包1.包2 import 包3 # 包2 init
# from 包1.包2.包3 import 文件 # 包3下 init
# import 包1
# 包1.包2.包3.文件.fun() 此时不会出错
# 绝对路径,直观,但移动不方便,
# 但调用不出错,随便使用
# ===================
# 使用相对路径
# from . import 包2 # 包1 下init
# from . import 包3 # 包2 init
# from . import 文件 # 包3下 init
# 找到包的位置,都可以使用包中的文件
# 注意:
# 包1/包2,包3,文件1
# 包2中文件调用 包3中文件 运行包2下那个文件 出错
# 若非要使用,在包2的那个文件中,添加包2的上级目录,即包1 进入sys.path
# 包2 文件 from 包3 import 包3文件 即可使用
# 文件1调用 包2,包3中文件 运行文件1 不出错
# #####文件1 调用包2文件引用文件3的那个方法(不错)
# 包中,包中文件调用出错,只有包外部文件可调用包内文件
# 相对路径,只能找到上层目录,但不能找到上层的上层
#======================
# 还有* 与__all__ 配合使用
#=======================================
# 总之,最重要的一点 from 或 import 包,文件的时候,看他是否在sys.path 中
#=======================================
# import os
# os.makedirs('glance/api')
# os.makedirs('glance/cmd')
# os.makedirs('glance/db')
# l = []
# l.append(open('glance/__init__.py','w'))
# l.append(open('glance/api/__init__.py','w'))
# l.append(open('glance/api/policy.py','w'))
# l.append(open('glance/api/versions.py','w'))
# l.append(open('glance/cmd/__init__.py','w'))
# l.append(open('glance/cmd/manage.py','w'))
# l.append(open('glance/db/models.py','w'))
# map(lambda f:f.close() ,l)
# import glance.api.policy as policy
# policy.get()
#
# from dir.glance.api import policy
# policy.get()
# import sys
# sys.path.insert(0,'C:\Users\Administrator\PycharmProjects\s9\day21\dir')
# # print(sys.path)
# from glance.api import policy
# policy.get()
# from dir import glance
# glance.db.models.register_models('mysql')
# glance.api.policy.get()
# 使用绝对路径 不管在包内部还是外部 导入了就能用
# 不能挪动,但是直观
# from dir import glance
# glance.api.policy.get()
# 相对路径
# 可以随意移动包 只要能找到包的位置,就可以使用包里的模块
# 包里的模块如果想使用其它模块的内容只能使用相对路径,使用了相对路径就不能在包内直接执行了
# bin
# start.py
# conf
# config.py
# my_log_setting.py
# setting.py
# core 核心代码
# core.py
# db 数据信息
# alex_json
# dzf_json
# lib 自定义模块,三方模块
# read_ini.py
# log
# access_log
# error_log
异常处理
代码语言:javascript复制# 语法错误,逻辑错误
# 1/0
# name
# 2 '3'
# [][3]
#{}['k']
# =========================================================
# try:
# print('1111')
# # 1/0
# print('2222')
# # name
# # 2 '3'
# # [][3]
# # {}['k']
# ret = int(input('number >>>'))
# print(ret*'*')
# except ValueError:
# print('输入的数据类型有误')
# except Exception:
# print('你错了,老铁')
# else:
# print('没有异常的时候执行else中的代码') # 正常执行完后执行,异常终止时,不处理
# =========================================================
# def func():
# try:
# f = open('file','w')
# ''''''
# return True
# except:
# return False
# finally:
# print('执行finally了')
# f.close()
#
# print(func())
# 程序一旦发生错误,就从错误的位置停下来了,不在继续执行后面的内容
# 使用try和except就能处理异常
#try是我们需要处理的代码
#except 后面跟一个错误类型 当代码发生错误且错误类型符合的时候 就会执行except中的代码
#except支持多分支
#有没有一个能处理所有错误的类型 : Exception
# 有了万能的处理机制仍然需要把能预测到的问题单独处理
# 单独处理的所有内容都应该写在万能异常之前
# else : 没有异常的时候执行else中的代码
# finally : 不管代码是否异常,都会执行
# finally和return相遇的时候 依然会执行
# 函数里做异常处理用,不管是否异常去做一些收尾工作 f.close,会先执行finally 再return
# try:
# main()
# except Exception:
# pass
try:
print('1111')
# 1/0
print('2222')
# name
# 2 '3'
# [][3]
# {}['k']
ret = int(input('number >>>'))
print(ret*'*')
except Exception as error: # 可输出错误信息
print('你错了,老铁',error)
面向对象
代码语言:javascript复制# 面向对象编程
# 所谓模子 就是 类 抽象的 我能知道有什么属性 有什么技能 但不能知道属性具体的值
# jin alex nezha 就是对象 有具体的值,属性和技能都是根据类规范的
# 自定义类
# def 函数名():
# pass
#=================
# class 类名:
# 属性 = 'a'
#=================
# print(类名.属性)
# 类名的作用 就是操作属性 查看属性
#==============================
# class Person: # 类名
# country = 'China' # 创造了一个只要是这个类就一定有的属性
# # 类属性 静态属性
# def __init__(self,*args): # 初始化方法,self是对象,是一个必须传的参数,等于构造方法
# # self就是一个可以存储很多属性的大字典 ,等于this, __dict__
# self.name = args[0] # 往字典里添加属性的方式发生了一些变化
# self.hp = args[1]
# self.aggr = args[2]
# self.sex = args[3]
#
# def walk(self,n): # 方法,(一般情况下必须传self参数),且必须写在第一个
# # 后面还可以传其他参数,是自由的
# print('%s走走走,走了%s步'%(self.name,n))
#========================================
# 静态属性查看
# # print(Person.country) # 类名 可以查看类中的属性,不需要实例化就可以查看
#========================================
# 普通属性查看
# alex = Person('狗剩儿',100,1,'不详') # 类名还可以实例化对象,alex对象 # 实例化
# print(alex.__dict__) # 查看所有属性
# print(alex.name) # 查看属性值
# print(alex.hp) # 查看属性值
#================================================
# 方法调用
# alex.walk(5) # 都可以调用
# Person.walk(alex,5) # 调用方法 类名.方法名(对象名)
#================================================
# print(Person.__dict__['country']) # 查看静态属性
# Person.__dict__['country'] = '印度'
# print(alex.__dict__['name'])
# alex.__dict__['name'] = '二哥'
# print(alex.__dict__)
# print(alex.name)
# print(alex.name)
# alex.name = '二哥'
# alex.__dict__['name'] = '二哥'
# alex.age = 83
# print(alex.__dict__)
# print(alex.name)
# 对象 = 类名()
# 过程:
# 类名() 首先 会创造出一个对象,创建了一个self变量
# 调用init方法,类名括号里的参数会被这里接收
# 执行init方法
# 返回self
# 对象能做的事:
# 查看属性
# 调用方法
# __dict__ 对于对象的增删改查操作都可以通过字典的语法进行,only contain dynamic attributes
# 类名能做的事:
# 实例化
# 调用方法 : 只不过要自己传递self参数
# 调用类中的属性,也就是调用静态属性
# __dict__ 对于类中的名字只能看 不能操作,用"."可以操作
# 几乎与java类似
# 定义类
# init方法
# self是什么 self拥有属性都属于对象
# 調用類的時候創建self,是一個空的對象,有init初始化
# 类中可以定义静态属性
# 类中可以定义方法,方法都有一个必须传的参数self
# 实例化
# 实例、对象
# 对象查看属性
# 对象调用方法
# 命名空間
# class has static attribute,function
# object has owner namespace,attribute not (contain static) attribute and a pointer to class,
# beacuse it, if you change class static attribute by obj , equal you change memory address ,if the attr is str,int and so on
# you will only change the one obj,it will add a dynamic attribute in obj’s __dict__
# if the static is list ,dict and so on, all obj and the static attr will be changed
# object execute the static attribute ,but can't find it ,will find it in class namespace
面向对象2
代码语言:javascript复制
代码语言:javascript复制# 导入包的时候,相当于实例化对象,对调用__init__ 在进行方法使用
# 面向对象:继承 多态 封装
# =======================
# 继承:单继承与多继承(独有)
# 父类,超类,基类
# 子类,派生类
# class Person:pass
# class Substance:pass
# class Student(Person,Substance):pass
#
# print(Student.__bases__) # (<class '__main__.Person'>, <class '__main__.Substance'>)
# print(Person.__bases__) # (<class 'object'>,) python3中,没有显示继承类,都默认继承object类
# class Animal:
# def __init__(self,name,aggr,hp):
# self.name = name
# self.aggr = aggr
# self.hp = hp
# self.func() # 子类的fun
# def func(self):
# print(123)
# #
# class Dog(Animal):
# def func(self):
# print(456)
# def bite(self,person):
# person.hp -= self.aggr
# d1 = Dog("dzf",1)
# print(d1)
# 子类没有init 会默认执行父类的init ,即把参数传给父类的init 注意与java不同
# 对于方法的重写,与java相同,字节实现自己的方法若要包含父类的方法Father.fun(self)即可 python3 中 有super
# super().__init__(x,x) 此种也可以,不用传递self
# super(原对象,self) 这两个参数是省略的
# 在类外部super(x,self).fun() 可调用x父类的fun方法
# 当子类有init时 调用自己的, super(x,y,x) ----> Father.__init__(self,x,y);self.z=z
# 推荐使用单继承,设计模式中 使用多继承,不常用
# 多继承
# 子类继承父类方法,并重写,切父类都有这个方法
# 父类的方法时,会按照次序,先自己,从左向右调用父类的
# 经典问题:钻石继承问题 图1,3
# 此时同父类:A B,C 继承A ,D继承BC, D调用方式,先按照顺序BC,再A
# 先广度找,再深度,广度优先 bc
# 若 B 继承A, C继承F D继承bc, 此时先 b a 再 c d
# 即若后边可以找到,就放在后边找,
# 按照(广度)优先遍历算法 ,不能重复 2
# python2中按照深度优先查找,一条路到黑
# 注意super() 再多继承时调用的不是父类的方法,而是按照查找顺序 调用 图4
# Class.mro() 列表返回class 到object 的继承顺序
# class A:pass
# class B(A):pass
# class C(A):pass
# class D(B):pass
# class E(C):pass
# class F(D,E):pass
#
# print(F.mro())
# 接口类:原生不支持
# 抽象类:原生支持
# from abc import abstractmethod,ABCMeta # 装饰器
# class Payment(metaclass=ABCMeta):
# @abstractmethod
# def pay(self,x):
# pass
# 规范
# 接口类,默认多继承,接口类中所有方法都要不实现(pass)
# 抽象类,不支持多继承,里面方法可以有一些实现 ,当两者书写形式相同
# 其他类继承时 必须要实现
# 接口隔离,一个接口与一个方法
# 本是没有接口的,因为自带多继承,通过这种方式模拟,接口 抽象类
# 与java相同,二者不能实例化
# python 天生支持多态 不用通过第三个类,实现一起调用
# 鸭子类型:依赖父类的情况下实现两个同名方法
# 封装性,隐藏属性,方法
class Person:
def __init__(self,name,passwd):
self.name=name
self.__passwd = passwd # 属性以双下划线开头 即为私有属性
dzf = Person("dzf","123456")
print(dzf)
print(dzf.name)
# print(dzf.passwd) # 打印出错
print(dzf.__dict__) # -->{'name': 'dzf', '_Person__passwd': '123456'}能查看
# 私有属性变为 “_类名属性名
# 对于方法相同,双下划线开头即为私有方法
# 静态属性也可定义为私有的
print(dzf._Person__passwd) # 能查到
# 没有真的约束,只是代码级别变形,外部通过——类名——名字 直接调用 内部——名字调用
# 父类的私有属性,子类不能调用(静态属性),
面向对象3
代码语言:javascript复制# isinstance(object,cls) # obj 是不是cls的子类
# issubclass(sub,super) sub 是super的子类
# __dict__ 类中中有方法,有属性,但方法不能通过dict执行
# 对象的__dict__只有属性
# sys.modules 列表显示模块简称:位置
# sys.modules['__main__'] 获取当前模块
# getattr(sys.modules['__main__'],xxx) # 从当前模块反射,防止其他模块重名反射
# 但一般不用__main__ 防止其他模块引用,用___name__代替
# 反射还可以拿到模块中的类,加括号 表示实例化
# 类中的内置方法,__init__,__str__,__repr__等,后两个必须返回字符串
# str(obj) -->obj.__str__ 等同于toString() 方法,默认情况继承object 打印地址
# __repr__ ,父类的一样也是打印地址
# %s 按照 __str__
# %r 按照__repr__
# repr 是str的备胎,若没有str,会找本类repr, 再找父类str,
# 但str不是repr的备胎,找不到子类repr 直接找父类repr 一般都实现repr
#内置方法很多,不一定都在obj __len__
# del 析构函数
# def __del__():pass
# del obj 先执行这个方法,再删除,即时不del 会在解释器结束的时候,调用del
# __call__ 方法
# a = A()()---> a()--->执行a的call方法,若没有则报错
# item系列
# class中实现item,可以通过 a['name']=a.name
# def __getitem__(self,item):
# if(hasattr(self,item))
# return getattr(self,item)
# f[item(属性名)]
# setitem
# def __setitem__(self,key,value): # 修改属性
# self.__dict__[key] = value
# 实现setitem,getitem后即可切片
# delitem
# 正常情况 del cls.name 对应的是 __delattr__(self,item):self.__dict__pop(item) object原生的
# def __delitem__(self,item):
# del self.__dict__[item]
#
# __init__ 初始化方法
# __new__构造方法:创建一个对象,不常用
# def __new__(cls,*args,**kwargs):
# return object.__new__(类名,*args,**kwargs) # 这两个参数可以不加,加了可能报错 此时没有self, 创建后给init
# 先执行new方法,再init
# 一个类 始终 只有 一个 实例
# 当你第一次实例化这个类的时候 就创建一个实例化的对象
# 当你之后再来实例化的时候 就用之前创建的对象
# class A:
# __instance = False
# def __init__(self,name,age):
# self.name = name
# self.age = age
# def __new__(cls, *args, **kwargs):
# if cls.__instance:
# return cls.__instance
# cls.__instance = object.__new__(cls)
# return cls.__instance
#
# egon = A('egg',38)
# egon.cloth = '小花袄'
# nezha = A('nazha',25)
# print(nezha)
# print(egon)
# print(nezha.name)
# print(egon.name)
# print(nezha.cloth)
# __eq__
# 默认对象"="比较 返回地址比较结果,写了__eq__之后 "=" 机会按照eq 与java不同
# is 比较的是地址,不绑定方法,当值str等直接存值的类型时,相同则返回True,其他类型 比较地址
# hash() 绑定__hash__ hash()中的是按照内存地址hash
# 通过修改__hash__ 可自定义hash,对于不可变类型,hash值相同
# nametuple 相当于创建一个类
list1 =[1,2,3] list('JQKA')
print(list1)
from random import shuffle # 打乱顺序,依赖__len__方法 ,__setitem__方法
shuffle(list1)
print(list1)
# set去重依赖hash() 与 eq方法
property
代码语言:javascript复制# property
# 内置装饰器函数 只在面向对象中使用,没什么其他的作用
from math import pi
class Circle:
def __init__(self,r):
self.r = r
@property
def perimeter(self):
return 2*pi*self.r
@property
def area(self):
return self.r**2*pi
# c1 = Circle(5)
# print(c1.area) # 圆的面积
# print(c1.perimeter) # 圆的周长
# class Person:
# def __init__(self,name,high,weight):
# self.name = name
# self.high = high
# self.weight = weight
# @property
# def bmi(self):
# return self.weight / self.high**2
# jin = Person('金老板',1.6,90)
# jin.bmi = 18 # 当做属性时,不能修改
# classmethod
# staticmethod
# class Person:
# def __init__(self,name):
# self.__name = name
# @property # 当做属性
# def na(self):
# return self.__name 'sb'
# @na.setter # 设置setter方法 3个na必须一致
# def na(self,new_name):
# self.__name = new_name
#
# tiger = Person('泰哥')
# print(tiger.name)
# tiger.name = '全班' # 可修改
# print(tiger.name)
# class Goods:
# discount = 0.8
# def __init__(self,name,price):
# self.name = name
# self.__price = price
# @property
# def price(self):
# return self.__price * Goods.discount
# apple = Goods('苹果',5)
# print(apple.price)
# 属性 查看 修改 删除
# class Person:
# def __init__(self,name):
# self.__name = name
# self.price = 20
# @property
# def name(self):
# return self.__name
# @name.deleter # 属性删除
# def name(self):
# del self.__name
# @name.setter
# def name(self,new_name): # 只能定义一个参数
# self.__name = new_name
# brother2 = Person('二哥')
# del Person.price
# brother2.name = 'newName'
# brother2
# del brother2.name
# print(brother2.name) # 查看报错 ,实际是私有的属性__name 没有了,调用了delete 内部语句 2个name()还存在
# 函数属于类,对象不能删除函数
反射
代码语言:javascript复制#反射 *****
# name = 'alex'
# 'name'
class Teacher:
dic = {'查看学生信息':'show_student','查看讲师信息':'show_teacher'}
def show_student(self):
print('show_student')
def show_teacher(self):
print('show_teacher')
@classmethod
def func(cls):
print('hahaha')
alex = Teacher()
# getattr(Teacher,'fun') # 只能获静态属性,类方法,(静态方法也可)返回方法地址,
# func = getattr(alex,'show_student') # 获取对象属性,变量 方法,动态属性
# func() 加括号即可调用
# 没有get到会报错
# hasattr getattr delattr
# if hasattr(Teacher,'dic'):
# ret = getattr(Teacher,'dic') # Teacher.dic # 类也是对象
# # ret2 = getattr(Teacher,'func') # 类.方法 teacher.func
# # ret2()
# print(ret)
# 通过反射
# 对象名 获取对象属性 和 普通方法
# 类名 获取静态属性 和类方法 和 静态方法
# 普通方法 self
# 静态方法 @staticmethod
# 类方法 @classmethod
# 属性方法 @property
class_static_method
代码语言:javascript复制# method 方法
# staticmathod 静态的方法 ***
# classmethod 类方法 ****
# 类的操作行为
# class Goods:
# __discount = 0.8
# def __init__(self,name,price):
# self.name = name
# self.__price = price
# @property
# def price(self):
# return self.__price * Goods.__discount
# @classmethod # 把一个方法 变成一个类中的方法,这个方法就直接可以被类调用,不用传入对象
# def change_discount(cls,new_discount): # 修改折扣,默认传入cls 表示类
# cls.__discount = new_discount
# apple = Goods('苹果',5)
# print(apple.price)
# Goods.change_discount(0.5) # Goods.change_discount(Goods) 默认传入cls
# print(apple.price)
# 当这个方法的操作只涉及静态属性的时候 就应该使用classmethod来装饰这个方法
# java
class Login:
def __init__(self,name,password):
self.name = name
self.pwd = password
def login(self):pass
@staticmethod
def get_usr_pwd(): # 静态方法 ,与类没有关系,不用传入cls
usr = input('用户名 :')
pwd = input('密码 :')
Login(usr,pwd)
Login.get_usr_pwd()
# 在完全面向对象的程序中,
# 如果一个函数 既和对象没有关系 也和类没有关系 那么就用staticmethod将这个函数变成一个静态方法
# 类方法和静态方法 都是类调用的
# 对象可以调用类方法和静态方法么? 可以 一般情况下 推荐用类名调用,与java相同
# 类方法 有一个默认参数 cls 代表这个类 cls
# 静态方法 没有默认的参数 和普通函数一样
常用模块
hashlib
代码语言:javascript复制# import hashlib
# md5 = hashlib.md5(bytes("盐值",encoding="utf8")) # 加颜值 sha1,sh3_224,sha3_512
# md5.update(b'dzf123') # 只能使用bytes类型,
# md5.update(b"123") # 支持分批加密
# print(md5.hexdigest()) #16进制
# 设置颜色
"""
33[显示方式;前景色;背景色m; xxx 33[0m
前:30-37 黑红绿黄,蓝紫青白
背:40-47 黑红绿黄,蓝紫青白
显示方式:0 终端默认显示
1 高亮显示
4 使用下划线
5 闪烁 (不好用)
7 反白显示
8 不可见
"""
# print("