1.1 random模块
import random 1.1.1 大于0且小于1之间的小数 print(random.random()) 1.1.2 大于等于1且小于等于3之间的整数 print(random.randint(1,3)) 1.1.3 大于等于1且小于3之间的整数 print(random.randrange(1,3)) 1.1.4 1或者alex或者sb print(random.choice([1,'alex','sb'])) 1.1.5 列表元素任意2个组合 print(random.sample([1,'alex','sb'],2)) 1.1.6 大于1小于4的小数,如1.927109612082716 print(random.uniform(1,4))
打乱数字顺序
l=[1,3,4,2,5] random.shuffle(l) print(l)
生成7位数校验码
def make_code(n): res='' for i in range(n): s1=str(random.randint(0,9)) s2=chr(random.randint(65,90)) res+=random.choice([s1,s2]) return res print(make_code(7))
1.2 os模块
os模块是与操作系统交互的一个接口
1.2.1 os.stat('path/filename') 获取文件/目录信息
print(os.stat(r'F:Python周末20期day61 本节内容').st_size) #文件大小
1.2.2 打印系统进程,无返回值
res=os.system('tasklist') print('====>',res)
1.2.3 将path分割成目录和文件名二元组返回
print(os.path.split(r'F:Python周末20期day61 本节内容'))
1.2.4 返回path的目录。其实就是os.path.split(path)的第一个元素
print(os.path.dirname(r'F:Python周末20期day61 本节内容'))
1.2.5 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
print(os.path.basename(r'F:Python周末20期day61 本节内容'))
1.2.6 如果path是绝对路径,返回True
print(os.path.isabs(r'C:\a123sz')) print(os.path.isabs(r'/root/a123sz'))
1.2.7 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
print(os.path.join('C:','D:\','dir1','dir2','a.txt')) print(os.path.join('D:\','dir1','dir2','a.txt'))
1.2.8 在Linux和Mac平台上,该函数会原样返回path,在windows平台上会将路径中所有字符转换为小写,并将所有斜杠转换为饭斜杠。
print(os.path.normcase('c:/windows\SYstem32\..'))
规范化路径,如..和/
print(os.path.normpath('c://windows\System32\../Temp/')) #C:windows emp
1.2.9 os路径处理
1.2.9.1 方式一:
F:Python周末20期day63 os模块.py....
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
1.2.9.2 方式二:
BASE_DIR=os.path.normpath(os.path.join( os.path.abspath(__file__), '..', '..' )) print(BASE_DIR)
1.2.10 返回path文件的大小
print(os.path.getsize(r'F:Python周末20期day61 本节内容'))
1.2.11 常用模块
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 输出操作系统特定的路径分隔符,win下为"\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为" ",Linux下为" "
os.pathsep 输出用于分割文件路径的字符串 win下为;,Linux下为:
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
os.path.getsize(path) 返回path的大小
1.3 sys模块
sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
import sys sys.argv sys.exit(0) sys.path
进度条的效果制定宽度
print('[%-50s]' %('#'*1)) print('[%-50s]' %('#'*2)) print('[%-50s]' %('#'*3)) print('[%-50s]' %('#'*4)) print('[%-50s]' %('#'*5))
打印%
([%-50s]) %('#'*10) print('[%%-%ds]' %50) #'[%-50s]'
可传参来控制宽度
print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10) print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10) print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10) print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)
打印%
print('%d%%' %30)
1.3.1 进度条功能
import time
#指定宽度
print('[%-15s]' %'#') print('[%-15s]' %'##') print('[%-15s]' %'###') print('[%-15s]' %'####')
#打印%
print('%s%%' %(100)) #第二个%号代表取消第一个%的特殊意义
#可传参来控制宽度
print('[%%-%ds]' %50) #[%-50s] print(('[%%-%ds]' %50) %'#') print(('[%%-%ds]' %50) %'##') print(('[%%-%ds]' %50) %'###')
#实现打印进度条函数
import sys import time def progress(percent,width=50): if percent >= 1: percent=1 show_str=('[%%-%ds]' %width) %(int(width*percent)*'#') print(' %s %d%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')
应用
def progress(percent,width=50): #进度条的宽度70 if percent >= 1: percent=1 show_str = ('[%%-%ds]' % width) % ('#' * int(width*percent)) print(' %s %d%%' %(show_str,int(100*percent)),end='') recv_size=0 total_size=10241 while recv_size < total_size: time.sleep(0.1) #模拟数据的传输延迟 recv_size+=1024 #每次收1024 progress(recv_size/total_size) #接收的比例
1.4 shutil模块
高级的 文件、文件夹、压缩包 处理模块
1.4.1 shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中
import shutil shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w')) shutil.copyfile(src, dst)
1.4.2 拷贝文件
shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
shutil.copymode(src, dst) 仅拷贝权限。内容、组、用户均不变
shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
shutil.copystat(src, dst) 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
1.4.2.1 shutil.copy(src, dst)
import shutil shutil.copy('f1.log', 'f2.log') 拷贝文件和权限 import shutil shutil.copy2('f1.log', 'f2.log') 拷贝文件和状态信息
1.4.2.2 shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
import shutil shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
1.4.2.3 拷贝软连接
import shutil shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
'''
通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
'''
1.4.3 shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
import shutil shutil.rmtree('folder1')
1.4.4 shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名。
import shutil shutil.move('folder1', 'folder3')
1.4.5 压缩解压缩
1.4.5.1 shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
创建压缩包并返回文件路径,例如:zip、tar
base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如 data_bak =>保存至当前路径
如:/tmp/data_bak =>保存至/tmp/
format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要压缩的文件夹路径(默认当前目录)
owner: 用户,默认当前用户
group: 组,默认当前组
logger: 用于记录日志,通常是logging.Logger对象
import shutil shutil.make_archive("bak", 'gztar', root_dir=r'F:Python周末20期day6') #tar cvzf bak.tar.gz /root
#将 /data 下的文件打包放置当前程序目录
import shutil ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
#将 /data下的文件打包放置 /tmp/目录
import shutil ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
1.4.5.2 zipfile压缩解压缩
import zipfile # 压缩 z = zipfile.ZipFile('laxi.zip', 'w') z.write('a.log') z.write('data.data') z.close() # 解压 z = zipfile.ZipFile('laxi.zip', 'r') z.extractall(path='.') z.close()
1.4.5.3 tarfile压缩解压缩
import tarfile # 压缩 >>> t=tarfile.open('/tmp/egon.tar','w') >>> t.add('/test1/a.py',arcname='a.bak') >>> t.add('/test1/b.py',arcname='b.bak') >>> t.close() 压缩 import tarfile t=tarfile.open('bak.tar.gz') t.extractall(r'F:Python周末20期day6aaa') t.close() # 解压 >>> t=tarfile.open('/tmp/egon.tar','r') >>> t.extractall('/egon') >>> t.close()
1.5 jison和pickle模块
之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值
dic={'a':1} with open('db.txt','w',encoding='utf-8') as f: f.write(str(dic)) with open('db.txt','r',encoding='utf-8') as f: dic=eval(f.read()) #"{'a':1}" print(dic['a']) 打印报错 eval("[null,false,1]")
无法解析null类型,而json就可以
import json dic={'a':1} x=None res1=json.dumps(dic) #str(dic) res2=str(dic) print(res1,type(res1)) print(res2,type(res2)) res=json.dumps(x) print(res,type(res))
1.5.1 json序列化
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
图1-1
图1-2
import json,time user={'name':'egon','age':18,'nb':True} with open('user.json','w',encoding='utf-8') as f: f.write(json.dumps(user)) #等价于json.dump(dic,f) students=['alex','egon','wxx','yxx'] json.dump(students,open('students.json','w',encoding='utf-8')) time.sleep(500)
1.5.2 pickle
图1-3
Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。
import pickle,json import pickle,json s={1,2,3} print(json.dumps(s)) print(pickle.dumps(s)) with open('s.pkl','wb') as f: #注意是w是写入str,wb是写入bytes,j是'bytes' f.write(pickle.dumps(s)) pickle.dump(s,open('s.pkl','wb'))
1.5.3 json反序列化
with open('s.pkl','rb') as f: s=pickle.loads(f.read()) #等价于s=pickle.load(f) print(s,type(s)) s=pickle.load(open('s.pkl','rb')) print(s, type(s))
无论数据是怎样创建的,只要满足json格式,就可以json.loads出来,不一定非要dumps的数据才能loads
1.6 shelve模块
shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型
import shelve f=shelve.open('db.shl') # f['stu1']={'name':'alex1','age':38} # f['stu2']={'name':'alex2','age':28} print(f['stu1']['name']) f.close()
1.7 xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
xml数据
<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>
xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml:
# print(root.iter('year')) #全文搜索
# print(root.find('country')) #在root的子节点找,只找一个
# print(root.findall('country')) #在root的子节点找,找所有
from xml.etree import ElementTree tree=ElementTree.parse('a.xml') root=tree.getroot() print(root.tag) print(root.attrib) print(root.text)
三种查找方式
从子节点中找
print(root.find('country')) print(root.findall('country')) print(root.find('rank')) #None
从正树形结构中查找
print(list(root.iter('rank'))) for country in root.findall('country'): rank=country.find('rank') print(rank.tag,rank.attrib,rank.text)
遍历文档树
for country in root: print('=============>',country.attrib['name']) for item in country: print(item.tag,item.attrib,item.text) for year in root.iter('year'): print(year.tag,year.attrib,year.text) for year in root.iter('year'): year.set('updated',"yes") year.text=str(int(year.text)+1) tree.write('a.xml')
#在country内添加(append)节点
for country in root: obj=ElementTree.Element('egon') #<egon name="egon" age="18">egon is good</egon> obj.attrib={'name':'egon','age':'18'} obj.text='egon is good' country.append(obj) tree.write('a.xml') for rank in root.iter('rank'): if int(rank.text) == 5: obj=ElementTree.Element('egon') #<egon name="egon" age="18">egon is good</egon> obj.attrib={'name':'egon','age':'18'} obj.text='egon is good' rank.append(obj) tree.write('a.xml')
1.8 configerparser模块
import configparser config=configparser.ConfigParser() config.read('my.ini') #查看所有的标题 print(config.sections()) #查看标题mysqld下所有key=value的key print(config.options('mysqld')) #查看标题mysqld下charater-server-set的值=>字符串格式 print(config.get('mysqld','charater-server-set')) if config.has_option('mysqld','aaa'): print(config.get('mysqld','aaa')) 查看标题mysqld下'skip-grant-table的值=>布尔值格式 print(config.getboolean('mysqld','skip-grant-table')) 查看标题mysqld'下port的值=>整数格式 print(config.getint('mysqld','port')) 查看标题mysqld'下port的值=> >浮点型格式 print(config.getfloat('mysqld','port')) 添加一个标题 config.add_section('egon') 在标题egon下添加name=egon,age=18的配置 config.set('egon','name','egon') config.set('egon','age','18') config.set('client','password','alex3714') 最后将修改的内容写入文件,完成最终的修改 config.write(open('my.ini','w',encoding='utf-8'))
1.9 hashlib模块
hash:一种算法 ,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
1.9.1 三个特点:
1.内容相同则hash运算结果相同,内容稍微改变则hash值则变
2.不可逆推
3.相同算法:无论校验多长的数据,得到的哈希值长度固定。
m=hashlib.md5() m.update('hello'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) m.update('world'.encode('utf-8')) print(m.hexdigest()) fc5e038d38a57032085441e7fe7010b0
m=hashlib.md5() m.update('hello'.encode('utf-8')) m.update('world'.encode('utf-8')) print(m.hexdigest()) m1=hashlib.md5() m1.update('hellowor'.encode('utf-8')) m1.update('l'.encode('utf-8')) m1.update('d'.encode('utf-8')) print(m1.hexdigest())
注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
18 但是update多次为校验大文件提供了可能。
name=input('user:>> ') pwd=input('password:>> ') m=hashlib.md5() m.update(pwd.encode('utf-8')) pwd=m.hexdigest() print(name,pwd)
1.9.2 模拟撞库
cryt_pwd='aee949757a2e698417463d47acac93df' pwds=[ 'alex3714', 'alex123', '123alex' ] def make_dic(pwds): dic={} for pwd in pwds: m=hashlib.md5(pwd.encode('utf-8')) dic[pwd]=m.hexdigest() return dic dic=make_dic(pwds) for pwd in dic: if dic[pwd] == cryt_pwd: print(pwd)
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密
import hashlib m=hashlib.sha512() m=hashlib.md5('一行白鹭上青天'.encode('utf-8')) m.update('alex3714'.encode('utf-8')) m.update('两个黄鹂鸣翠柳'.encode('utf-8')) print(m.hexdigest()) python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密: import hmac m=hmac.new('加盐'.encode('utf-8')) m.update('alex3714'.encode('utf-8')) print(m.hexdigest())
#要想保证hmac最终结果一致,必须保证:
#1:hmac.new括号内指定的初始key一样
#2:无论update多少次,校验的内容累加到一起是一样的内容
import hmac h1=hmac.new(b'egon') h1.update(b'hello') h1.update(b'world') print(h1.hexdigest()) h2=hmac.new(b'egon') h2.update(b'helloworld') print(h2.hexdigest()) h3=hmac.new(b'egonhelloworld') print(h3.hexdigest()) ''' f1bf38d054691688f89dcd34ac3c27f2 f1bf38d054691688f89dcd34ac3c27f2 bcca84edd9eeb86f30539922b28f3981 '''
1.10 subprocess模块
import subprocess import time subprocess.Popen('tasklist',shell=True) print('----->主') time.sleep(1) import time import subprocess obj=subprocess.Popen('tasklist',shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) print(obj) print('第1次:',obj.stdout.read()) print('第2次:',obj.stdout.read()) print('---->主') print(obj.stdout.read().decode('gbk'))
#等同于上面,但是上面的优势在于,一个数据流可以和另外一个数据流交互,可以通过爬虫得到结果然后交给grep
import subprocess #ls /etc ;pwd;ps aux obj=subprocess.Popen('tssssasklist',shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) print(obj.stdout.read()) print(obj.stderr.read().decode('gbk')) 了解 import subprocess #tasklist | findstr python obj=subprocess.Popen('tasklist | findstr python',shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) print(obj.stdout.read()) obj1=subprocess.Popen('tasklist',shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) obj2=subprocess.Popen('findstr python',shell=True, stdin=obj1.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) print(obj2.stdout.read()) #subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码
面向对象
1.11 类的定义与使用
1.11.1 面向过程与面向对象
面向过程:核心是过程二字,过程即解决问题的步骤,就是先干什么再干什么
基于该思想写程序就好比在设计一条流水线,是一种机械式的思维方式
优点:复杂的过程流程化,进而简单化
缺点:扩展性差
面向对象:核心是对象二字,对象是特征与技能的结合体
基于该思想编写程序就好比在创造一个世界,世界是由一个个对象组成,是一种“上帝式”的思维方式
优点:可扩展性强
缺点:编程复杂高,容易出现过度设计
1.11.2 类
对象是特征与技能的结合体,类就是一系列对象相似的特征与技能的结合体
在现实世界中:一定是先有的一个个具体存在的对象,后总结出的类
在程序中:一定保证先定义类,后产生对象
1.11.3 站在老男孩学校的角度
现实中的对象:
对象1:
特征
学校=老男孩
名字=李三炮
性别=男
年龄=18
技能
学习
选课
对象2:
特征
学校=老男孩
名字=张铁蛋
性别=女
年龄=38
技能
学习
选课
对象3:
特征
学校=老男孩
名字=武大郎
性别=男
年龄=28
技能
学习
选课
对象4:
特征
学校=老男孩
名字=egon
性别=男
年龄=18
技能
教学
现实中的老男孩学生类:
老男孩学生类
相似的特征
学校=老男孩
相似的技能
学习
选课
'''
# 类体代码在类的定义阶段就会立刻执行,
class Student: school='oldboy' def learn(self): print('is learning') def choose_course(self): print('choose course') # print('====run') # print(Student) # print(Student.__dict__) #查看 # print(Student.school) #数据属性 # print(Student.learn) #函数属性 #增加 # Student.country='China' # print(Student.country) #修改 # Student.school='Oldboy' # print(Student.school) #删除 # del Student.country # print(Student.country) # print(Student.learn) # Student.learn('xxxxx')
1.12 对象的定义与使用
1.12.1 面向过程与面向对象
面向过程:核心是过程二字,过程即解决问题的步骤,就是先干什么再干什么
基于该思想写程序就好比在设计一条流水线,是一种机械式的思维方式
优点:复杂的过程流程化,进而简单化
缺点:扩展性差
面向对象:核心是对象二字,对象是特征与技能的结合体
基于该思想编写程序就好比在创造一个世界,世界是由一个个对象组成,是一种“上帝式”的思维方式
优点:可扩展性强
缺点:编程复杂高,容易出现过度设计
1.12.2 类
对象是特征与技能的结合体,类就是一系列对象相似的特征与技能的结合体
在现实世界中:一定是先有的一个个具体存在的对象,后总结出的类
在程序中:一定保证先定义类,后产生对象
1.12.3 站在老男孩学校的角度
现实中的对象:
对象1:
特征
学校=老男孩
名字=李三炮
性别=男
年龄=18
技能
学习
选课
对象2:
特征
学校=老男孩
名字=张铁蛋
性别=女
年龄=38
技能
学习
选课
对象3:
特征
学校=老男孩
名字=武大郎
性别=男
年龄=28
技能
学习
选课
对象4:
特征
学校=老男孩
名字=egon
性别=男
年龄=18
技能
教学
现实中的老男孩学生类:
老男孩学生类
相似的特征
学校=老男孩
相似的技能
学习
选课
'''
class Student: school='oldboy' #stu1,'李三炮','男',18 def __init__(self,name,sex,age): #在调用类时会自动触发执行 self.Name=name self.Sex=sex self.Age = age #stu1.Name='李三炮' #stu1.Sex='男' #stu1.Age=18 def learn(self): print('is learning') def choose_course(self): print('choose course') #调用类的过程又称之为实例化:stu1=Student('李三炮','男',18) #1、得到一个返回值,即对象,该对象是一个空对象stu1 #2、Student.__init__(stu1,'李三炮','男',18) stu1=Student('李三炮','男',18) # print(stu1.__dict__) # print(stu1.Name,stu1.Age,stu1.Sex) stu2=Student('张铁蛋','女',38) stu3=Student('武大郎','男',28) # print(stu2.__dict__) # print(stu3.__dict__) # print(stu1,stu2,stu3) # print(stu2.Name)
1.13 属性查找与绑定方法
x=1 class Student: school='oldboy' # Name='xxx' def __init__(self,name,sex,age): #在调用类时会自动触发执行 self.Name = name self.Sex = sex self.Age = age #stu1.Name='李三炮' #stu1.Sex='男' #stu1.Age=18 def learn(self,x,y): print('%s is learning' %self.Name) print(x,y) def choose_course(self): print('choose course') def commit_hw(): print('commit homework')
1.13.1 查找一个对象的属性顺序是:先找对象自己的__dict__,再找类的__dict__
# stu1=Student('李三炮','男',18) # # print(stu1.__dict__) # # # print(stu1.Name) # # print(stu1.school) # # print(stu1.x) stu1=Student('李三炮','男',18) stu2=Student('张铁蛋','女',38) stu3=Student('武大郎','男',28)
1.13.2 类的数据属性是所有对象共享,所有对象都指向同一个内存地址
# stu1.school='xxx' # Student.school='Oldgirl' # print(Student.school,id(Student.school)) # print(stu1.school,id(stu1.school)) # print(stu2.school,id(stu2.school)) # print(stu3.school,id(stu3.school))
# 3、类中定义的函数是绑定给对象使用:
# 3.1:不同对象就是不同绑定方法
# 3.2:绑定给谁,就应该由谁来调用,谁来调用就会把谁当做第一个参数传给对应的函数
# print(Student.learn) # print(stu1.learn) # print(stu2.learn) # print(stu3.learn) # stu1.learn(1,2) #Student.learn(stu1,1,2) # stu2.learn(1,3) # stu3.learn(1,4) # print(Student.learn) # stu1.commit_hw()
1.13.3 小练习
class Teacher: school='oldboy' count=0 def __init__(self,name,sex,age,level,salary): self.name=name self.sex=sex self.age=age self.level=level self.salary=salary Teacher.count+=1 def teach(self): print('%s is teaching' %self.name) t1=Teacher('egon','male',18,10,3000) t2=Teacher('alex','female',38,9,30000) t3=Teacher('wxx','female',28,10,30000) print(t1.count) print(t2.count) print(t3.count)
class Garen: camp='demacia' def __init__(self,nickname,life_value,aggresivity): self.nickname=nickname self.life_value=life_value self.aggresivity=aggresivity def attack(self,enemy): enemy.life_value-=self.aggresivity class Riven: camp = 'Noxus' def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity def fire(self,enemy): enemy.life_value-=100 g1=Garen('草丛猥琐男',1000,100) r1=Riven('猛男雯雯',200,500) print(r1.life_value) g1.attack(r1) print(r1.life_value)
1.14 类即类型
# class Teacher: # school='oldboy' # count=0 # # def __init__(self,name,sex,age,level,salary): # self.name=name # self.sex=sex # self.age=age # self.level=level # self.salary=salary # Teacher.count+=1 # # def teach(self): # print('%s is teaching' %self.name) # # t1=Teacher('egon','male',18,10,3000) # print(type(t1)) # l=[1,2,3,4] #l=list([1,2,3,4]) # print(type(l)) l1=list([1,2,3,4]) l2=list([1,2,3,4]) # print(id(l1)) # print(id(l2)) # print(l1.append) # l1.append(5) #list.appent(l1,5) # list.append(l1,5) # print(l1) l1.append('a') l2.append('b')
1.15 从代码级别看面向对象
1.15.1 在没有学习类这个概念时,数据与功能是分离的
def exc1(host,port,db,charset,sql): conn=connect(host,port,db,charset) res=conn.execute(sql) return res def exc2(host,port,db,charset,proc_name) conn=connect(host,port,db,charset) res=conn.call_proc(prco_name) return res
#每次调用都需要重复传入一堆参数
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') exc2('127.0.0.1',3306,'db1','utf8','存储过程的名字') exc1('127.0.0.1',3306,'db1','utf8','select * from tb2;')
1.15.2 在没有学习类这个概念时,数据与功能是分离的
host='127.0.0.1' port=3306 db='db1' charset='utf-8' x=1 y=2 def exc1(sql): conn=connect(host,port,db,charset) res=conn.execute(sql) return res def exc2(proc_name) conn=connect(host,port,db,charset) res=conn.call_proc(prco_name) return res def func1(): print(x) print(y) def func2(): print(x) print(y)
#每次调用都需要重复传入一堆参数
exc1('select * from tb1;') exc2('utf8','存储过程的名字') exc1('select * from tb2;') func()
1.15.3 使用类
# class Mysqlhandle: # def __init__(self,host,port,db,charset='utf-8'): # self.host=host # self.port=port # self.db=db # self.charset=charset # self.conn=connect(host,port,db,charset) # # def exc1(self,sql): # return self.conn.execute(sql) # # def exc2(self,proc_name) # return self.conn.call_proc(prco_name) # # obj1=Mysqlhandle('127.0.0.1',3306,'db1') # # obj1.exc1('select * from t1') # obj1.exc1('select * from t2') # obj1.exc1('select * from t3') # obj2=Mysqlhandle('10.10.10.9',3306,'db2') # obj2.exc1('select * from t1 where id > 3')