内容简介:模块与对象(六)
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期\day6\1 本节内容').st_size) #文件大小
1.2.2 打印系统进程,无返回值
res=os.system('tasklist')
print('====>',res)
1.2.3 将path分割成目录和文件名二元组返回
print(os.path.split(r'F:\Python周末20期\day6\1 本节内容'))
1.2.4 返回path的目录。其实就是os.path.split(path)的第一个元素
print(os.path.dirname(r'F:\Python周末20期\day6\1 本节内容'))
1.2.5 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
print(os.path.basename(r'F:\Python周末20期\day6\1 本节内容'))
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\temp
1.2.9 os路径处理
1.2.9.1 方式一:
F:\Python周末20期\day6\3 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期\day6\1 本节内容'))
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下为"\t\n",Linux下为"\n"
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('\r%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('\r%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.1shutil.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期\day6\aaa')
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.2pickle
图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')
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Node内建模块和对象
- 自省?使用inspect模块探测python对象内容
- apache – 无法在@INC中找到模块main的可加载对象
- Node.js基础 23456:全局对象,回调函数,模块,事件,读写文件(同步,异步)
- 音乐播放器项目,gulp+面向对象+异步回调+fs模块模拟数据库项目
- 微信模块 Oejia_wx v0.6.2 发布,缓存对象配置模型等多项优化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。