面向对象

三、类的属性查找

类有两种属性:数据属性和函数属性

  1. 类的数据属性是所有对象共享的

  2. 类的函数属性是绑定给对象用的

class Heros: birthplace='王者荣耀' def attcck(self): #普通的攻击技能 passhero1=Heros()hero2=Heros()hero3=Heros()#类的数据属性是所有对象共享的,id都一样print(id(Heros.birthplace))print(id(hero1.birthplace))print(id(hero2.birthplace))print(id(hero3.birthplace))'''4651296465129646512964651296'''#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样#ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准print(Heros.attcck)print(hero1.attcck)print(hero2.attcck)print(hero3.attcck)'''<function Heros.attcck at 0x0000000001E81730><bound method Heros.attcck of <__main__.Heros object at 0x0000000001E7E7F0>><bound method Heros.attcck of <__main__.Heros object at 0x0000000001E7E780>><bound method Heros.attcck of <__main__.Heros object at 0x0000000001E7E828>>'''

在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
 

#类的数据属性是所有对象共享的,id都一样print(id(OldboyStudent.school))print(id(s1.school))print(id(s2.school))print(id(s3.school))'''4377347328437734732843773473284377347328'''#类的函数属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样#ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准print(OldboyStudent.learn)print(s1.learn)print(s2.learn)print(s3.learn)'''<function OldboyStudent.learn at 0x1021329d8><bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x1021466d8>><bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146710>><bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x102146748>>'''

一、 什么是面向对象的程序设计及为什么要有它

1、面向过程

  面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式。

  优点是复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现,实现小的步骤将会非常简单)

  缺点是一套流水线或者流程就是用来解决一个问题,牵一发而动全身。

  应用场景:一旦完成基本很少改变的场景。

2、面向对象 

  面向对象的程序设计:核心是对象二字,对象是特征与技能的结合体,基于面向对象设计程序就好比在创造一个世界,你就是这个世界的主宰,存在的皆为对象,不存在的也可以创造出来,与面向过程机械式的思维方式形成鲜明对比,面向对象更加注重对现实世界的模拟,是一种“主宰式”的思维方式。

  优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。

  缺点:

  1. 编程的复杂度远高于面向过程,一些扩展性要求低的场景使用面向对象会徒增编程难度,比如管理linux系统的shell脚本就不适合用面向对象去设计,面向过程反而更加适合。

  2. 无法向面向过程的程序设计流水线式的可以很精准的预测问题的处理流程与结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法准确地预测最终结果。于是我们经常看到对战类游戏,新增一个游戏人物,在对战的过程中极容易出现阴霸的技能,一刀砍死3个人,这种情况是无法准确预知的,只有对象之间交互才能准确地知道最终的结果。

  应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方

面向对象的程序设计并不是全部。对于一个软件质量来说,面向对象的程序设计只是用来解决扩展性。

图片 1

四、shutil模块

二 、类与对象

  类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体

那么问题来了,先有的一个个具体存在的对象(比如一个具体存在的人),还是先有的人类这个概念,这个问题需要分两种情况去看

在现实世界中:先有对象,再有类

  世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念

也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在

在程序中:务必保证先定义类,后产生对象

  这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类

不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象

按照上述步骤,我们来定义一个类:

#在程序中,务必保证:先定义类,后调用类来产生对象PS: 1. 在程序中特征用变量标识,技能用函数标识 2. 因而类中最常见的无非是:变量和函数的定义#程序中的类class Heros: birthplace='王者荣耀' def attcck(self): #普通的攻击技能 pass#注意: 1.类中可以有任意python代码,这些代码在类定义阶段便会执行 2.因而会产生新的名称空间,用来存放类的变量名与函数名,可以通过Heros.__dict__查看 3.对于经典类来说我们可以通过该字典操作类名称空间的名字(新式类有限制),但python为我们提供专门的.语法 4.点是访问属性的语法,类中定义的名字,都是类的属性#程序中类的用法.:专门用来访问属性,本质操作的就是__dict__Heros. birthplace #等于经典类的操作Heros.__dict__['birthplace']Heros. birthplace='王者荣耀' #等于经典类的操作Heros.__dict__['birthplace']='王者荣耀'Heros.x=1 #等于经典类的操作Heros.__dict__['x']=1del Heros.x #等于经典类的操作Heros.__dict__.pop('x')#程序中的对象#调用类,或称为实例化,得到对象hero1=Heros()hero2=Heros()hero3=Heros()#如此,hero1、hero2、hero3都一样了,而这三者除了相似的属性之外还各种不同的属性,这就用到了__init__#注意:该方法是在对象产生之后才会执行,只用来为对象进行初始化操作,可以有任意代码,但一定不能有返回值class Heros: ...... def __init__(self,name,atk,hp): self.name=name self.atk=atk self.hp=hp ......hero1=Heros('盖伦',200,200) #先调用类产生空对象hero1,然后调用Heros.__init__(hero1,'盖伦',200,200)hero2=Heros('诺克萨斯之手',150,200)hero3=Heros('托儿索',100,200)#程序中对象的用法#执行__init__,hero1.name='盖伦',很明显也会产生对象的名称空间hero1.__dict__{'name': '盖伦', 'atk': 200, 'hp': 200}hero1.name #hero1.__dict__['name']hero2.name='诺克萨斯之手' #hero2.__dict__['name']='诺克萨斯之手'

PS:

1. 站的角度不同,定义出的类是截然不同的,

2.
现实中的类并不完全等于程序中的类,比如现实中的公司类,在程序中有时需要拆分成部门类,业务类...... 

3.
有时为了编程需求,程序中也可能会定义现实中不存在的类,比如策略类,现实中并不存在,但是在程序中却是一个很常见的类

#python为类内置的特殊属性类名.__name__# 类的名字(字符串)类名.__doc__# 类的文档字符串类名.__base__# 类的第一个父类(在讲继承时会讲)类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)类名.__dict__# 类的字典属性类名.__module__# 类定义所在的模块类名.__class__# 实例对应的类(仅新式类中)
[section1]k1 = v1k2:v2user=egonage=18is_admin=truesalary=31[section2]k1 = v1

四、 绑定到对象的方法的特殊之处

#改写class Heros: def __init__(self,name,atk,hp): self.name=name self.atk=atk self.hp=hp def attcck(self,enemy): # 普通的攻击技能   print("%s攻击%s"%(self,enemy))hero1=Heros('盖伦',200,200) #先调用类产生空对象hero1,然后调用Heros.__init__(hero1,'盖伦',200,200)hero2=Heros('诺克萨斯之手',150,200)hero3=Heros('托儿索',100,200)

类中定义的函数(没有被任何装饰器装饰的)是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个参数:

Heros.attcck(hero1,hero2) # 盖伦攻击诺手Heros.attcck(hero2,hero3) # 诺手攻击儿索Heros.attcck(hero3,hero1) # 儿索攻击盖伦

类中定义的函数(没有被任何装饰器装饰的),其实主要是给对象使用的,而且是绑定到对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法

强调:绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理):

hero1.attcck(hero2) # 盖伦攻击诺手hero2.attcck(hero3) # 诺手攻击儿索hero3.attcck(hero1) # 儿索攻击盖伦

注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,self可以是任意名字,但是约定俗成地写出self。

 

类即类型

  python中一切皆为对象,且python3中类与类型是一个概念,类型就是类

#类型dict就是类dict>>> list<class 'list'>#实例化的到3个对象l1,l2,l3>>> l1=list()>>> l2=list()>>> l3=list()#三个对象都有绑定方法append,是相同的功能,但内存地址不同>>> l1.append<built-in method append of list object at 0x10b482b48>>>> l2.append<built-in method append of list object at 0x10b482b88>>>> l3.append<built-in method append of list object at 0x10b482bc8>#操作绑定方法l1.append(3),就是在往l1添加3,绝对不会将3添加到l2或l3>>> l1.append(3)>>> l1[3]>>> l2[]>>> l3[]#调用类list.append(l3,111)等同于l3.append(111)>>> list.append(l3,111) #l3.append(111)>>> l3[111] 

 

 

OldboyStudent.learn(s1) #李坦克 is learningOldboyStudent.learn(s2) #王大炮 is learningOldboyStudent.learn(s3) #牛榴弹 is learning

读取:

 

shutil.rmtree(path[, ignore_errors[, onerror]])递归的去删除文件1 import shutil2 3 shutil.rmtree('folder1')shutil.move(src, dst)递归的去移动文件,它类似mv命令,其实就是重命名。1 import shutil2 3 shutil.move('folder1', 'folder3')shutil.make_archive(base_name, format,...)创建压缩包并返回文件路径,例如:zip、tar创建压缩包并返回文件路径,例如:zip、tarbase_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,如 data_bak =>保存至当前路径如:/tmp/data_bak =>保存至/tmp/format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”root_dir: 要压缩的文件夹路径(默认当前目录)owner: 用户,默认当前用户group: 组,默认当前组logger: 用于记录日志,通常是logging.Logger对象复制代码1 #将 /data 下的文件打包放置当前程序目录2 import shutil3 ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')4 5 6 #将 /data下的文件打包放置 /tmp/目录7 import shutil8 ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data') 

生成随机码

  类即类别、种类,是面向对象设计最重要的概念,对象是特征和技能的结合体,而类则是一系列对象相似的特征和技能的结合体。

  应用场景:需求经常变化的软件,一般需求的变化量都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象程序。

三、sys模块

 

import sysimport time# 打印进度条# print('[%-15s]' %'#')# print('[%-15s]' %'##')# print('[%-15s]' %'###')# print('[%-15s]' %'####')def progress(percent,width=50): if percent >= 1: percent = 1 show_str = ('[%%-%ds]' %width) % (int(width*percent) * '#') print('r%s %s%%' %(show_str,int(100*percent)),file=sys.stdout,flush=True,end='')data_size = 102500recv_size = 0while recv_size < data_size: time.sleep(0.5) recv_size+=1024

 

obj.name会先从obj自己的名称空间找name,找不到则去类中找,类也找不到就去找父类,最后找不到会抛出异常。

  1:持久保持状态

为什么要序列化?

  2: 跨平台数据交互

1 import pickle 2 3 dic={'name':'alvin','age':23,'sex':'male'} 4 5 print(type(dic))#<class 'dict'> 6 7 j=pickle.dumps(dic) 8 print(type(j))#<class 'bytes'> 9 10 11 f=open('序列化对象_pickle','wb')#注意是w是写入str,wb是写入bytes,j是'bytes'12 f.write(j) #-------------------等价于pickle.dump(dic,f)13 14 f.close()15 #-------------------------反序列化16 import pickle17 f=open('序列化对象_pickle','rb')18 19 data=pickle.loads(f.read())# 等价于data=pickle.load(f)20 21 22 print(data['age']) 
<?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>
#os路径处理#第一种 有利于跨平台possbile_topdir = os.path.normpath(os.path.join( os.path.abspath(__file__), os.path.pardir, os.path.pardir, os.path.pardir,))sys.path.insert(0,possbile_topdir)#第二种os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

 

 

 

  图片 2

shutil 对压缩包的处理是调用 ZipFile 和 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()# 解压>>> t=tarfile.open('/tmp/egon.tar','r')>>> t.extractall('/egon')>>> t.close()

zipfile压缩解压缩

 

import configparserconfig=configparser.ConfigParser()config.read('a.cfg',encoding='utf-8')#删除整个标题section2config.remove_section('section2')#删除标题section1下的某个k1和k2config.remove_option('section1','k1')config.remove_option('section1','k2')#判断是否存在某个标题print(config.has_section('section1'))#判断标题section1下是否有userprint(config.has_option('section1',''))#添加一个标题config.add_section('egon')#在标题egon下添加name=egon,age=18的配置config.set('egon','name','egon')config.set('egon','age',18) #报错,必须是字符串#最后将修改的内容写入文件,完成最终的修改config.write(open('a.cfg','w'))
import jsonx = "[null,true,false,1]"# print(eval(x)) #使用eval()就会报错print(json.loads(x))

    序列化之后,不仅可以吧序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好使用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

#python为类内置的特殊属性类名.__name__# 类的名字(字符串)类名.__doc__# 类的文档字符串类名.__base__# 类的第一个父类(在讲继承时会讲)类名.__bases__# 类所有父类构成的元组(在讲继承时会讲)类名.__dict__# 类的字典属性类名.__module__# 类定义所在的模块类名.__class__# 实例对应的类(仅新式类中)

类有两种属性:数据属性和函数属性

#在country内添加(append)节点year2import xml.etree.ElementTree as ETtree = ET.parse("a.xml")root=tree.getroot()for country in root.findall('country'): for year in country.findall('year'): if int(year.text) > 2000: year2=ET.Element('year2') year2.text='新年' year2.attrib={'update':'yes'} country.append(year2) #往country节点下添加子节点tree.write('a.xml.swap')
1 sys.argv 命令行参数List,第一个元素是程序本身路径2 sys.exit(n) 退出程序,正常退出时exit(0)3 sys.version 获取Python解释程序的版本信息4 sys.maxint 最大的Int值5 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值6 sys.platform 返回操作系统平台名称

xml数据格式

 

 

 

#在现实世界中,站在老男孩学校的角度:先有对象,再有类对象1:李坦克 特征: 学校=oldboy 姓名=李坦克 性别=男 年龄=18 技能: 学习 吃饭 睡觉对象2:王大炮 特征: 学校=oldboy 姓名=王大炮 性别=女 年龄=38 技能: 学习 吃饭 睡觉对象3:牛榴弹 特征: 学校=oldboy 姓名=牛榴弹 性别=男 年龄=78 技能: 学习 吃饭 睡觉现实中的老男孩学生类 相似的特征: 学校=oldboy 相似的技能: 学习 吃饭 睡觉
#改写class OldboyStudent: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def learn(self): print('%s is learning' %self.name) #新增self.name def eat(self): print('%s is eating' %self.name) def sleep(self): print('%s is sleeping' %self.name)s1=OldboyStudent('李坦克','男',18)s2=OldboyStudent('王大炮','女',38)s3=OldboyStudent('牛榴弹','男',78)复制代码

面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,面向过程是一种机械式的思维。

 

面向对象的程序设计:核心是对象二字。对象是特征和技能的结合体,面向对象更加注重对现实世界的模拟。

#####面向对象#####

类与对象

  2、现实中的类并不完全等同于程序中的类。

pickle

五,json&pickle模块

    在断电或者重启程序之前将程序当前内存中所有的数据都保存下来,(保存到文件中)以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,就是序列化。

八、hashlib模块

   json和python内置的数据类型对应:

注意的地方:

 

 

import random# print(random.random()) #打印0-1之间的小数# print(random.randint(1,3)) #大于等于1小于等于3之间的整数# print(random.randrange(1,5)) #大于等于1小于5之间的整数# print(random.choice([1,'23',[4,5]])) #1或者23,或者[4,5] random.choice([list])# print(random.sample([1,'23',[4,5]],2)) #random.sample([1,2,3,4,5],2)(k=[1,2,3,4,5],n=2) k列表中的任意n个组合

什么是序列化?

 

  json表示出来就是一个字符串,可以被所有语言读取,也可以方便的存储到磁盘或者通过网络传输,json不仅是标准格式,并且比xml更快,而且可以直接在web页中读取。

  优点:复杂的问题流程化,进而简单化。

在程序中:

相关文章

Comment ()
评论是一种美德,说点什么吧,否则我会恨你的。。。