python自动化_day7_面向对象进阶
面向对象的复习:类--->类的初始化--->对象的创造---->属性和方法,组合,继承,多态,封装
1 #面向对象复习 2 # 类 实例化 对象/实例 3 # 什么是类?拥有相同属性和方法的一类事物 4 # 什么是对象?类的实际的表现,给类中的属性填上具体的值,能够使用类中的方法 5 # 实例化的过程当中做了哪些事? 6 # 对象 = 类名() 7 # 首先要创造一个对象 8 # 被创造出来的这个对象会作为参数传递给init方法中的第一个参数 9 # 然后才是调用内置的__init__方法,传递一些初始化的参数,init就是初始化方法 10 # 将初始化之后的对象返回给调用者 11 # 查看属性和调用方法 12 # 类名 : 静态属性 、 类属性 13 # 对象 : 调用方法(动态属性)、自动的把对象本身传进去,查看对象的属性 14 # 组合 : 两类事物之间的所有(什么有什么)关系,学生有课程 班级有课程 15 # 继承 : 两个类之间的包含关系,什么是什么的关系,人是动物 白马是马 16 # 钻石继承问题: 17 # 经典类:在一个子类中寻找方法的时候,从子类到父类先找到的名字会被执行 18 # 深度优先就是在经典类中找类的顺序的一种算法 19 # 新式类:广度优先 20 # py2中,主动继承object类的都是新式类,他的子类也是新式类 21 # py3中,所有的类都是新式类,都继承object 22 # super 23 # 自己有父类也有的时候,单继承super就可以用父类的属性 24 # 在多继承中,super遵循mro广度优先顺序 25 # 派生: 26 # 属性 27 # 方法 28 # 多态: 29 # py中不需要程序员自己实现多态
封装:把函数和变量放在类中算一种广义的封装,把一些变量和方法隐藏起来,不对外公开,是python中的封装 __名字
1 #人狗大战,把狗和人的动作放进人和狗的类里 这就算一种封装 2 class Dog: 3 role = 'dog' 4 def eat(self):pass 5 Dog.role 6 class Person: 7 # __country = '中国' #私有的静态属性 8 # print(__country) #类里面的代码什么时候执行。在自定义阶段就执行了,函数永远不执行。 9 # def func(self):pass #函数加载到类里的内存空间里 10 # print(Person.__country) #AttributeError: type object 'Person' has no attribute '__country' 11 #私有的名字,只能在类的内部使用,不能再类的外部使用 12 print(Person.__dict__) #'_Person__country': '中国' 13 print(Person._Person__country)#不能使用这种方法调用私有变量 14 # 如果非要在类的外部调用一个私有的名字,必须是在私有的名字前面加_类名__私有名字 15 Person.__name = 'xxx' #在类的外部不能定义一个私有变量,只能在类内部 16 print(Person.__dict__)
私有的变量:类的内部如果使用__变量的形式会发生变形,python会自动的为你机上‘__类名’的形式
1 class Person: 2 __country = '中国' 3 def __init__(self,name,pwd): 4 self.name = name 5 self.__pwd = pwd 6 def login(self): 7 print(self.__dict__) 8 if self.name == 'alex' and alex.__pwd == 'alex3714': 9 print('welcome') 10 alex = Person('alex','alex3714') 11 print(alex.__dict__) 12 alex.login() 13 class Person: 14 def __init__(self):pass 15 def __制造密码转换(self):print('eating') 16 def 注册(self): 17 inp = input('>>>>') 18 加密之后的密码 = self.__制造密码转换(inp)
静态属性、对象属性、方法 前面加上双下划綫都会变成私有的。只能内部调用,不能外部使用
1 #面试 2 class Foo: 3 def __init__(self): 4 self.__func() 5 def __func(self): 6 print('in foo') 7 class Son(Foo): 8 def __func(self): 9 print('in son') 10 s = Son()
########################################装饰器方法############################
1 ########property 2 from math import pi 3 class Circle: 4 def __init__(self,r): 5 self.r = r 6 @property 7 def area(self): 8 return self.r ** 2 * pi 9 @property 10 def perimeter(self): 11 return self.r * 2* pi 12 h = Circle(5) 13 print(h.area) 14 print(h.perimeter) 15 #方法 都是动词 ---- 动作或者技能 16 #圆形类的面积和周长都是名词 调用的时候是按照方法嗲用的 17 #将一个函数伪装成为属性 @property 18 #一个方法已经做了伪装之后就不可以在加()调用 19 class Vol: 20 def __init__(self,x,y,z): 21 self.__x = x 22 self.__y = y 23 self.__z = z 24 @property 25 def v(self): 26 return 2 * self.__x * self.__y + 2 * self.__y * self.__z + 2 * self.__x * self.__z 27 c = Vol(5,10,4) 28 print(c.v)
#########################property 和 __私有的名字合用#############################
1 class Goods: 2 def __init__(self,price,discount): 3 self.__price = price #把原价隐藏起来做成一个私有变量 4 self.discount = discount 5 @property 6 def price(self): 7 return self.__price * self.discount 8 @price.setter #修改前提就是已经对price做装饰了,先有了属性伪装才可以修改 9 def price(self,new_price):self.__price = new_price 10 @price.deleter 11 def price(self):del self.__price 12 apple = Goods(8,0.8) 13 print(apple.price) 14 #如果价格变了 应该怎么办 私有变量不可以修改了 15 apple.price = 10 16 print(apple.price) 17 print(apple.__dict__) 18 del apple.price 19 print(apple.__dict__)
###############################classmethod类方法###############################
1 class Foo: 2 country = '中国人' 3 @classmethod #把方法变成类方法, 4 def func(cls): #cls指向类的内存空间 5 print('当前的角色国籍都是%s' % cls.country) 6 Foo.func() 7 #类方法在什么时候使用,如果某一个类中的方法,并没有用这个类的实例中的具体属性 8 #只是用到了类中的静态变量,就是用类方法
###############################staticmethod方法#################################
1 #如果一个方法 既不会用到对象中的属性,也不会用到类中的属性 2 #就应该被定义为静态方法 3 class Student: 4 @staticmethod 5 def login(): 6 name = input('name:') 7 pwd = input('pwd:') 8 if name == '' and pwd == '': 9 print('登录成功之后实例化') 10 Student.login()
###############################序列化模块#####################################
1 #什么叫序列化 2 #l = {'101122':{'name':'','age':'1'}} 3 #序列化存储 必须转换成字符串才可以存储 str() 4 #拿出数据来 = = eval() 不安全会被其他利用 所以不适用eval 5 #数据类型转换成字符串的过程就叫序列化 6 #什么时候要用序列化 7 #数据从内存到文件 8 #数据在网络上传输 字节<<<---->>>字符串<<<----->>>字典 9 #python中的序列化模块都有哪些 10 #json 是所有语言当初都有的数据类型 支持的数据类型少 list tuple str dict 11 #pickle 在python通用的 支持几乎所有python中的数据类型 12 #shelve python3版本中不太好用 适用的便捷的序列化工具 13 14 #dumps loads 在内存中序列化的模块 15 #dump load 在文件里序列化的模块 16 import json 17 dic = {'k':'v'} 18 json_dic = json.dumps(dic) 19 dic_new = json.loads(json_dic) 20 print(dic_new) 21 print(type(dic_new)) 22 with open('d.txt','a') as f: 23 json.dump(dic,f) #dump 是和文件交互的 24 with open('d.txt') as f: 25 print(json.load(f)) 26 27 #如果要dump多条数据 28 #每条数据先dumps一下,变成字符串 然后打开文件write写进文件里 \n 29 #读取的时候按照标志读取或者按行读 30 #读出来之后 在使用loads 31 with open('aaa','w') as f: 32 str_dic = json.dumps(dic) #把dic dumps到内存里 33 f.write(str_dic + '\n') 34 f.write(str_dic + '\n') 35 f.write(str_dic + '\n') 36 f.write(str_dic + '\n') 37 f.write(str_dic + '\n') 38 f.write(str_dic + '\n') 39 f.write(str_dic + '\n') 40 with open('aaa') as f: 41 for line in f: 42 print(json.loads(line.strip())) 43 import pickle 44 class A: 45 def __init__(self,name): 46 self.name = name 47 alex = A('alex') 48 json.dumps(alex) #json 不可以序列化 49 print(pickle.dumps(alex)) 50 with open('ccc','ab') as f: 51 pickle.dump(alex,f) 52 pickle.dump(alex,f) 53 pickle.dump(alex,f) 54 with open('ccc','rb') as f: 55 while True: 56 try: 57 obj = pickle.load(f) 58 print(obj.name) 59 except EOFError:break 60 # piekle 好处 61 #1.pickle 支持更多的数据类型 62 #2.pickle 的结果是二进制 63 #3. pickle在和文件交互的时候可以被多次load 64 # 1、在生产中,dumps和loads只进行一次,而且要用w把原来的数据冲掉,从而保证每次都是最新的。 65 # 2、虚拟机的快照,是每个快照都有一个文件,而不是全都不放在一起。 66 # 3、如果想生产好几个序列化,就生成多个文件。 67 # 4、json和pickle又有相同的方法: 68 # json:用于(不同平台和多语言)字符串和python数据类型进行转换 69 # pickle:用于python特有的类型和python的数据类型间进行转换(所有python数据类型) 70 # json:模块提供了四个功能:dumps dump loads load 71 # pickle:模块提供了四个功能:dumps dump loads load 72 # (1)、在内存中修改,通过write和read、for循环的方式读写到文件中: 73 # dumps:f.write(jsoin | pickle.dumps(info)) 74 # loads:json | pickle.loads(f.read()) 75 # 76 # (2)、直接写文件,无需其他方法: 77 # dump: json | pickle.dump(info, f) 78 # load:data = json | pickle.load(f)
#######################常用模块 hashlib logging configparserr#######################
1 #讲一个字符串进行摘要运算 拿到一个固定的值 2 #不是一个算法,包含多种算法的模块 3 md5obj = hashlib.sha1() #md5 sha1 可以随意使用 其他都一样 最常用的是md5和sha 4 # #一种算法 实例化一个md5摘要算法的对象#能够让一个字符串 唯一的 对应 一个固定的值 5 md5obj.update('alex3714'.encode('utf-8')) #使用md5算法的对象来操作字符串 basis类型 6 ret = md5obj.hexdigest() #hex digest 16进制 计算 #获取算法的结果 7 print(ret,type(ret),len(ret)) 8 #注册 :输入密码 进行一次摘要 存储到文件里 9 #登录 :登录密码 进行摘要 和文件里做对比 10 11 #撞库的问题 防止撞库可以做 加盐 12 md5obj = hashlib.sha1('alex'.encode('utf-8')) 13 md5obj.update('alex3714'.encode('utf-8')) 14 ret = md5obj.hexdigest() 15 print(ret) 16 #动态加盐 使用注册用户名加盐 用户名注册之后就不能修改了 17 user = input('') 18 md5obj = hashlib.sha1(user.encode('utf-8')) 19 md5obj.update('alex3714'.encode('utf-8')) 20 ret = md5obj.hexdigest() 21 print(ret) 22 23 #校验文件的一致性 24 #自动化 ----py的代码做验证 25 md5obj = hashlib.sha1() 26 md5obj.update('alex3714'.encode('utf-8')) 27 ret = md5obj.hexdigest() 28 print(ret) 29 md5obj = hashlib.sha1() 30 md5obj.update('alex'.encode('utf-8')) 31 md5obj.update('3714'.encode('utf-8')) 32 ret = md5obj.hexdigest() 33 print(ret)
1 #configparser模块 2 config["DEFAULT"] = {'ServerAliveInterval': '45', 3 'Compression': 'yes', 4 'CompressionLevel': '9', 5 'ForwardX11':'yes' 6 } 7 8 config['bitbucket.org'] = {'User':'hg'} 9 config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} 10 with open('example.ini', 'w') as f: 11 config.write(f) 12 config = configparser.ConfigParser() 13 config.read('example.ini') 14 print(config.sections()) # ['bitbucket.org', 'topsecret.server.com'] # DEFAULT --> 全局 15 16 print('bytebong.com' in config) # False 17 print('bitbucket.org' in config) # True 18 print(config['bitbucket.org']["user"]) # hg 19 print(config['DEFAULT']['Compression']) #yes 20 print(config['topsecret.server.com']['ForwardX11']) #no 21 print(config['bitbucket.org']) #<Section: bitbucket.org> 生成器 22 for key in config['bitbucket.org']: # 注意,有default会默认default的键 23 print(key) 24 print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键 25 print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对 26 print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value 27 28 import configparser 29 config = configparser.ConfigParser() 30 config.read('example.ini') 31 config.add_section('yuan') 32 config.remove_section('bitbucket.org') 33 config.remove_option('topsecret.server.com',"forwardx11") 34 config.set('topsecret.server.com','k1','11111') 35 config.set('yuan','k2','22222') 36 config.write(open('example.ini', "w"))
##############################logging模块######################################
1 #日志模块 2 #一些程序的中间过程需要记录下来,作为后期参考数据 对内看的 3 #对外看的日志 给用户看的日志 记录一些用户行为和代码的执行过程 4 #简单配置 5 logging.basicConfig(level=logging.DEBUG, 6 format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', 7 datefmt='%a, %d %b %Y %H:%M:%S', 8 filename='test.log', 9 filemode='w') #级别控制 10 logging.debug('debug message') #非常细节的日志 排查错误时候使用 11 logging.info('info message' ) #正常的日志信息 12 logging.warning('warning message') #警告信息 13 logging.error('error message') #错误信息 14 logging.critical('critical message') #重大错误 程序直接崩溃 15 # logger对象的方式配置 16 logger = logging.getLogger()#使用logger对象的方式跟吸星大法差不多 17 #先创造一个格式 18 logger.setLevel(logging.DEBUG) 19 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 20 formatter1 = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s') 21 fh = logging.FileHandler('log.log',encoding='utf-8') #往文件输入 #创造了一个能操作文件的对象 22 fh.setFormatter(formatter) 23 logger.addHandler(fh) 24 sh = logging.StreamHandler() 25 sh.setFormatter(formatter1) 26 logger.addHandler(sh) 27 fh.setLevel(logging.DEBUG) 28 sh.setLevel(logging.DEBUG) 29 logger.debug('logger debug message') 30 logger.info('logger info message') 31 logger.warning('logger warning message') 32 logger.error('程序出错了') 33 logger.critical('logger critical message')
######################################反射####################################
1 #什么叫反射 2 #通过字符串类型的 变量问来访问变量的值 3 # name = 'value' 4 # 获取字符串类型的变量名 来操作文件 5 #类名反射 静态属性 6 #对象名反射 对象属性和方法 7 #模块反射 模块中的名字 8 #反射自己所在文件中的名字 9 # xx.yy 这样的形式都可以用反射 10 print('aaa'.startswith('a')) 11 #'startswith' 12 ret = getattr('aaa','startswith') 13 print(ret('a')) 14 class Person: 15 role = 'person' 16 def __init__(self,name):self.name = name 17 def eat(self):print('eating') 18 def drink(self):print('drinking') 19 def play(self):print('playing') 20 def sleep(self):print('sleepping') 21 alex = Person('alex') 22 print(getattr(alex,'name')) 23 print(getattr(alex,'role')) 24 while True: 25 inp = input('>>>>') 26 if hasattr(alex,inp): 27 getattr(alex,inp)() 28 #首先使用getattr获取一个名字,如果在这个对象的命名空间中没有这个名字,会报错 29 #getattr的反射好伴侣 hasattr 30 #如果使用getattr获取一个方法,那么只能拿到这个方法的内存地址 31 #加上括号就是执行 当然,括号里的参数可以照传不误 32 #如果geattr获取一个属性,那么直接使用反射获取值就可以获取到值 33 import mymodule 34 import time 35 mymodule.func1() 36 getattr(mymodule,'func1')() 37 getattr(time,'sleep')(1) 38 print(getattr(mymodule,'money')) 39 Manager = getattr(mymodule,'Manager') 40 a = Manager() 41 a.eat() 42 import sys 43 value = '123' 44 print(sys.modules['__main__']) #反射自己模块中的 45 print(getattr(sys.modules['__main__'],'value'))
单例模式和new方法
1 # 在面向对象的里面 会有很多(__方法__) 2 # __new__ 构造方法 创建一个对象 3 #__init__ 初始化方法 实例化一个对象 4 class Foo: 5 def __new__(cls, *args, **kwargs): 6 print('执行我啦') 7 return object.__new__(cls) 8 def __init__(self):print('222222') 9 Foo() 10 #先执行new方法,object.new() 11 #在执行init方法 12 13 #Foo() ------>>> py解释器接收到你的python代码 14 #pyton解释器替你去做了很多操作 15 #包括主动帮助你 调用new方法 去创造一个对象 ------>>>开辟内存空间 ----python语言封装了开辟内存的工作 16 #object的new方法里做了 开辟空间 创建对象的工作 17 #调用init 用到的self 就是new帮你创造的对象 18 #翻译成C语言的字节码 19 #将C语言的字节码解释成机器码 让CPU去执行 20 21 #单例模式 #个人理解就是开辟一个最初的命名空间 里面的对象名字可以改变 22 #什么叫单例模式 某一个类 只有一个实例 23 class Person: 24 __isinstance = None 25 def __new__(cls, *args, **kwargs): 26 if not cls.__isinstance: 27 obj = object.__new__(cls) 28 cls.__isinstance = obj 29 return cls.__isinstance 30 def __init__(self,name): 31 self.name = name 32 alex = Person('alex') 33 print(alex.name) 34 egon = Person('egon') 35 print(egon.name)
#############内置len方法和内置str方法############################################
1 class A: 2 pass 3 def __len__(self): 4 return 10 5 a = A() 6 print(len(a)) 7 #类中的内置方法 很多都和内置函数相关 8 #__hash__ 9 class B: 10 def __init__(self,name):self.name = name 11 def __str__(self): 12 return 'b obj of person named %s' %self.name 13 def __hash__(self): 14 return 1 15 b = B('alex') 16 print(hash(b)) 17 print(b)