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)
posted @ 2018-05-25 16:59  张腾飞♂  阅读(234)  评论(0编辑  收藏  举报