面向对象进阶和模块初识
本篇内容主要是面向对象的进阶和模块的初识,主要包括如下内容:接口类和抽象类、封装、类方法、静态方法、属性、反射、特殊方法、序列化模块、random模块。
1.接口类抽象类
''' 整体说明: 01 在python中的接口类和抽象类的含义是一样的,其他语言中接口类和抽象类的定义不同。 02 python中的接口类定义:制定一个规则,让其他人按照我的规则去写程序。(约定俗成,有些野蛮程序员可能不会遵循) 03 python接口类的形式:(约定俗成的规范,即如果在一个类中出现如下形式,则说明是python的接口类定义) # class payment: # 类名根据实际的需求进行定义 # def func(self): # 函数的参数根据实际的需求进行补充和完善;函数名根据实际的要求进行定义。 # pass 04 python接口类(强制规范)形式: # from abc import ABCMeta, abstractmethod # 该处引用是必须的,如果强制规范的接口类,必须进行引用。 # class payment(metaclass=ABCMeta): # 类名根据实际的需求进行定义 # @abstractmethod # def func(self): # 函数的参数根据实际的需求进行补充和完善;函数名根据实际的要求进行定义。 # pass 05 在编写代码的时候需要遵循“归一化”设计,即比如线上支付,支付的手段有QQ、微信、支付宝三种支付方式,最后统一的调用支付接口的时候,尽量定义统计的调用方式进行(下面会有具体的示例展示)。 ''' # 1.支付方式不统一 class QQpay:def pay(self, money):print('QQ支付了%s钱' % money)class Alipay:def pay(self, money):print('支付宝支付了%s钱' % money)a1 = QQpay() a1.pay(100) b1 = Alipay() b1.pay(200)# 2.统一支付方式:归一化设计class QQpay:def pay(self, money):print('QQ支付了%s钱' % money)class Alipay:def pay(self, money):print('支付宝支付了%s钱' % money)def pay(obj, money): # 归一化设计,设计统一的调用方式 obj.pay(money)a1 = QQpay() b1 = Alipay() pay(a1, 100) pay(b1, 200)# 3.接口类定义:制定一个规则,让其他人按照我的规则去写程序。 class payment: # 定义接口类,让所有人都遵循这个方式进行定义支付类。def pay(self, money):passclass QQpay(payment):def pay(self, money):print('QQ支付了%s钱' % money)class Alipay(payment):def pay(self, money):print('支付宝支付了%s钱' % money)class Wechat(payment):def fuqian(self, money):print('微信支付了%s钱' % money)def pay(obj, money): # 归一化设计 obj.pay(money)# 4.接口类定义(强制规范): from abc import ABCMeta, abstractmethod # 通过引用实现强制规范的接口类class payment(metaclass=ABCMeta):@abstractmethod # 引用装饰器,实现强制规范接口类。def pay(self, money):passclass QQpay(payment):def pay(self, money):print('QQ支付了%s钱' % money)class Alipay(payment):def pay(self, money):print('支付宝支付了%s钱' % money)# 错误写法 class Wechat(payment):def fuqian(self, money): # 该处未按照标准的格式来,所以,在调用该类的时候会报错,应该讲方法fuqian修改为pay即可print('微信支付了%s钱' % money)# 正确写法 class Wechat(payment):def pay(self, money): # 该处未按照标准的格式来,所以,在调用该类的时候会报错,应该讲方法fuqian修改为pay即可print('微信支付了%s钱' % money)def pay(obj, money): # 归一化设计 obj.pay(money)w = Wechat() pay(w, 100)
2.封装
''' 01 封装的定义(1)广义的封装:将一些内容放到一个‘容器’中。(2)狭义的封装:私有 02 私有成员:(1)私有成员包括私有变量,私有对象属性,私有方法。(2)私有成员类外面不能访问,派生类不可以访问,类内可以访问。 03 类的结构:静态变量(属性,字段)、私有静态变量、动态普通方法、私有方法、特殊方法(双下划下方法)、私有对象属性属性、类方法、静态方法。 '''# 01 类的结构 class B:country = 'China' # 静态变量(属性,字段)__name = 'alex' # 私有静态变量def func(self): # 动态普通方法passdef __func(self): # 私有方法passdef __init__(self, name, age): # 特殊方法:双下方法self.name = nameself.__age = age # 私有对象属性 @property # 属性def f1(self):pass@classmethod # 类方法def func2(self):pass@staticmethod # 静态方法def func3(self):pass# 02 私有成员:类外面不能访问,派生类不可以访问,类内可以访问。 class A:country = 'China' # 静态变量(属性,字段)__name = 'alex' # 私有静态变量def __init__(self, name, age):self.name = nameself.__age = agedef func(self): # 动态普通方法print(self.__name)def __func(self): # 私有方法passclass B(A):def func2(self):print(self.__name)obj = A('二狗', 18) print(obj.country) # 类外面可以访问 # print(obj.__name) # 私有:类外面不可以访问 obj.func() # 私有:类内面可以访问 o1 = B('脸哥', 25) o1.func2() # 私有:派生类不可以访问 obj = A('二狗', 18) print(A.__dict__) # print(obj._A__name)
3.类方法
''' 整体说明: 01 必须通过类的调用,而且此方法的意义在于对类里面的变量或者方法进行修改添加。 02 类方法通过使用装饰器“@classmethod”来标记,同时装饰器下面的方法中的变量必须默认为“cls”。 '''# 01 类方法说明: class B:country = 'China' # 静态变量(属性,字段)def func(self): # 动态普通方法passdef __init__(self, name, age): # 特殊方法:双下方法self.name = name@classmethod # 类方法def func2(cls): # 对B类进行修改,封装了2个属性,即area和namecls.area = '东北'cls.name = '马玉刚' print(B) ''' 运行结果:<class '__main__.B'> ''' print(B.__dict__) ''' 运行结果: {'__module__': '__main__', 'country': 'China', 'func': <function B.func at 0x0000000001E9DF28>, '__init__': <function B.__init__ at 0x0000000001EA2048>, 'func2': <classmethod object at 0x0000000001E9E9E8>,'__dict__': <attribute '__dict__' of 'B' objects>, '__weakref__': <attribute '__weakref__' of 'B' objects>,'__doc__': None} ''' B.func2() print(B.__dict__) ''' 运行结果:' {'__module__': '__main__', 'country': 'China', 'func': <function B.func at 0x0000000001E9DF28>, '__init__': <function B.__init__ at 0x0000000001EA2048>, 'func2': <classmethod object at 0x0000000001E9E9E8>,'__dict__': <attribute '__dict__' of 'B' objects>, '__weakref__': <attribute '__weakref__' of 'B' objects>,'__doc__': None, 'area': '东北', 'name': '狗哥'} '''# 02 类方法应用:统计类实例对象的个数class C:count = 0def __init__(self): # 实例化对象默认必须执行__init__函数 C.cou()@classmethoddef cou(cls):cls.count += 1obj = C() obj = C() obj = C() obj = C() obj = C() obj = C() obj = C() obj = C() obj = C() obj = C() obj = C() print(C.count)''' 运行结果:11 '''
4.静态方法
''' 整体说明: 01 静态方法定义:在类中,一个不依赖类以及对象的一个普通函数。 02 静态方法作用:保证代码的一致性,可调控性,整洁性。 '''# 1. 静态方法示例 class C:def __init__(self):pass@staticmethoddef func(*args, **kwargs): # 该方法可以独立与类C存在,不依赖类和对象存在。print(666) C.func() c1 = C() c1.func()# 2. 静态方法示例 import timeclass TimeTest(object):def __init__(self, hour, minute, second):self.hour = hourself.minute = minuteself.second = second@staticmethod # 静态方法def showTime():return time.strftime("%H:%M:%S", time.localtime())''' 说明: 01 将以下方法移动至TimeTest仍可以正常执行,与类和对象无关。def showTime():return time.strftime("%H:%M:%S", time.localtime()) '''
5.属性
''' 整体说明: 01 property:是将方法伪装成为一个属性。 02 property引用形式:在方法前加上装饰器@property 进行伪装即可。 03 property的作用:代码层面上没有提升,但是他会让你的代码看起来更合理。在对象进行方法调用的时候,无需在方法名后加括号即可调用方法。 04 property的装饰器是成对出现的:@property 、@AAA.setter、 @AAA.deleter,其中@property最为常用和重要。(1)@property:对象执行get的时候运行装饰器下的方法。(2)@AAA.setter:对象执行set的时候运行该装饰器下的方法。(3)@AAA.deleter:对象执行删除的时候运行该装饰器下的方法。 05 在进行setter和deleter的时候,方法名和调用装饰器的方法名必须保持一致。 '''# 01 属性:为什么要进行伪装。 ''' 需求:测试人体的BMI值 '''class B:def __init__(self, name, weight, height):self.name = nameself.weight = weightself.height = height@propertydef bmi(self):return self.weight / self.height ** 2gouge = B('马玉刚', 90, 1.78) print(gouge.bmi)# 说明:bmi看起来应该是一个名字,但是你用一个方法去实现,所以为了符合逻辑性,增加属性装饰器@property来进行。 # 由于伪装成为属性,所以在调用方法的时候无需在方法名后面加括号。# 02 属性的说明 class Foo:def __init__(self,name):self.name = name@property # ***def AAA(self):print('get的时候运行我啊')@AAA.setter # *def AAA(self,value):print('set的时候运行我啊')@AAA.deleter # *def AAA(self):print('delete的时候运行我啊') obj = Foo('alex') obj.name = '太白' print(obj.name) # del obj.name # print(obj.name) obj.AAA = 666 # 对伪装的属性进行改值是就会调用 def AAA(self,value): del obj.AAA # 对伪装的属性进行detele的时候进行运行@AAA.deleter下的方法。# 03 属性应用1: ''' 需求: 01 苹果的原始价位8元,折扣价格:0.8折,求苹果的售卖单价。 02 苹果的原始价格7元,折扣不变,求苹果的售卖店家。 03 原始价格和折扣都是私有变量。 '''class Product:def __init__(self, name, origin_price, discount):self.name = nameself.__origin_price = origin_priceself.__discount = discount@propertydef price(self):return self.__origin_price * self.__discount@price.setterdef price(self, new_price):self.__origin_price = new_priceapple = Product('苹果', 8, 0.95) print(apple.price) apple.price = 7 print(apple.price)
6.反射
''' 整体说明: 01 反射的定义:通过字符串去操作对象(实例化对象,类,模块) 02 反射应用场景如下:(1)反射可以对实例化对象使用。(2)反射可以对类使用。(3)反射可以对当前模块使用。(4)反射可以对其他模块使用。 03 反射的方法:(1)hasattr() :判断是否存在某个变量或者方法。 ***(2)getattr() :以字符串的形式获取某个变量或者方法。 ***(3)setattr() :对某个变量或者方法进行设置。 *(4)delattr() :对某个变量或者方法进行删除。* 04 isinstance:判断的是obj是否是此类或者此类的子孙类实例化出来的对象。 # isinstance(obj, B) 05 issubclass: 判断B是否是A的子类或者孙类。 # issubclass(B, A) ''' # # 01 isinstance:判断的是obj是否是此类或者此类的子孙类实例化出来的对象。 class A: passclass B(A): passobj = B() print(isinstance(obj, B)) # True print(isinstance(obj, A)) # True# 02 issubclass:判断B是否是A的子类或者孙类。 # issubclass(B, A) class C: passclass A(C): passclass B(A): passabj = B()print(issubclass(B, A)) # True print(issubclass(B, C)) # True# 03 反射对实例化对象应用的示例。 class A:def __init__(self, name, age):self.name = nameself.age = ageobj = A('脸哥', 27)ret = getattr(obj, 'name', None) # getattr获取对象中的name,如果没有返回None print(hasattr(obj, 'age')) # hasattr判断对象中是否有age,有返回True,没有返回False print(ret) if hasattr(obj, 'name'):ret = getattr(obj, 'name')setattr(obj, 'sex', '男') # 设置 print(getattr(obj, 'sex'))delattr(obj, 'name') # 删除 print(obj.__dict__)# 03 反射对类应用的示例。class A:name = 'alex'def __init__(self):passdef func(self):print('IN func')ret = input('>>>>') # 输入func,并且将func赋值给ret f1 = getattr(A, ret)(1) # 通过getattr执行func方法,方法名+()调用方法执行方法,()中的1是需要给方法中传进入一个变量,变量任意。''' 说明: 通过类名调用类中的方法时其实是在执行函数func,并不是类中的方法,所以并不会自动赋值给self,所以需要是手动赋值,可以是任意值。 '''# 04 反射在当前模块中的应用。 def func():print('in func')import syscurrent_module = sys.modules[__name__]getattr(current_module, 'func')()# 05 反射在对其他模块(文件)应用的示例。 import fs # fs为自定义模块print(getattr(fs, 'n1')) ret = getattr(fs, 'func') ret()# 方法一: clas = getattr(fs, 'A') print(clas.name)# 方法二: print(getattr(fs.A, 'name')) getattr(fs.A, 'func2')(1)
7.特殊方法
''' 整体说明: 01 单例设计模式:让一个类的实例化对象有且只有一个 *** 02 __init__和__new__的先后顺序。(1)第一步:__new__先要new出一个对象(__new__方法在object类中默认的方法)(2)第二步:根据创建出的类,通过__init__进行属性的封装。 03 __call__方法。 04 __item__系列:对一个对象进行类似于字典的操作,就会触发__item__系列的某个方法。 ***(1)__getitem__(2)__setitem__(3)__delitem__ 05 __str__:遇到print()后即触发该方法执行。 06 __repr__:遇到print()后即触发该方法执行。 07 __call__:对象+(),触发该方法。 '''# 01 __str__:遇到print()后即触发该方法执行。 class A:def __init__(self):passdef __str__(self):print(666)return '马玉刚'a = A() ret = '姓名:%s' % a print(ret)''' 运行结果: 666 姓名:马玉刚 '''# 02 __repr__:遇到print()后即触发该方法执行。class A:def __init__(self):passdef __repr__(self):return '马玉刚'a = A() print('%r' % a) # 马玉刚# 03 __call__:对象+(),触发该方法。class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print(args)print('__call__')obj = Foo() obj('WuSir', 'alex') # 对象() 触发 __call__()方法''' 运行结果: ('WuSir', 'alex') __call__ '''# 04 单例设计模式'''未采用单例设计模式''' class A:passret = A() ret1 = A() print(ret, ret1)''' 运行结果:两个不同的地址 <__main__.A object at 0x00000000021DE908> <__main__.A object at 0x00000000021DE940> ''''''采用单例设计模式,单例设计模式有7种方式,以下是一种常用的单例设计模式''' class A:__instance = Nonedef __new__(cls, *args, **kwargs):if cls.__instance is None:obj = object.__new__(cls)cls.__instance = objreturn cls.__instanceret1 = A() ret2 = A() ret3 = A() print(ret1, ret2, ret3)''' 运行结果:同一地址 <__main__.A object at 0x00000000021DE978> <__main__.A object at 0x00000000021DE978> <__main__.A object at 0x00000000021DE978> '''# 05 __item__系列 __getitem__ __setitem__ __delitem__ *** # 对一个对象进行类似于字典的操作,就会触发__item__系列的某个方法。 class Foo:def __init__(self, name):self.name = namedef __getitem__(self, item):print('__getitem__此方法执行了')return self.__dict__[item]def __setitem__(self, key, value):print('__setitem__此方法执行了')self.key = valuedef __delitem__(self, key):print('del obj[key]时,我执行')self.__dict__.pop(key)def __delattr__(self, item):print('del obj.key时,我执行')self.__dict__.pop(item)f = Foo('alex') print(f['name']) # f[name]属于查的方式,所以触发了__getitem__方法。 f['age'] = 25 # 触发了__setitem__的方法。 del f['name'] # 触发了__delitem__方法 print(f.__dict__)
8.序列化模块
''' 整体说明: 01 模块定义:一个py文件就是一个模块。 02 模块的分类:(1)内置模块: time os random shelve re 等等。(2)拓展模块:beautifulsoup iteat等大神写的模块。(3)自定义模块:自己整理的模块。 03 序列化模块:(1)JSON:适用于所有语言。(1)网络传输:dumps loads(2)文件写入:dump load(2) pickle 只用于Python语言之间的传输,包含所有的python支持的数据类型。(3)shelve :直接对文件句柄操作,就可以存入数据。 04 python和JSON的转换# +-------------------+---------------+ # | Python | JSON | # += == == == == == == == == == += == == == == == == == + # | dict | object | # +-------------------+---------------+ # | list, tuple | array | # +-------------------+---------------+ # | str | string | # +-------------------+---------------+ # | int, float | number | # +-------------------+---------------+ # | True | true | # +-------------------+---------------+ # | False | false | # +-------------------+---------------+ # | None | null | # +-------------------+---------------+''' import json import pickle# 01 JSON序列化 # dumps loads # 网络传输 dic = {'name': '二狗', 'age': 25, 'sex': '男'} ret = json.dumps(dic, ensure_ascii=False) # 序列化过程 : 就是变成一个特殊的字符串 respon = json.loads(ret) # 反序列化:将序列化的特殊字符串反解成原来的类型。 print(ret, type(ret)) print(dic) print(respon, type(respon))# dump load 写入常规文件 dic = {1: {'username': '二狗1', 'password': 123},2: {'username': '二狗2', 'password': 123},3: {'username': '二狗3', 'password': 123},} f = open('json_file', 'w') json.dump(dic, f) # dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件 f.close()f = open('json_file') dic2 = json.load(f) # load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回 print(dic2, type(dic2)) f.close() print(type(dic2), dic2)# 02 pickle 只用于Python语言之间的传输,包含所有的python支持的数据类型。 dic = {'name': '二狗', 'age': 25, 'sex': '男'} ret = pickle.dumps(dic) respon = pickle.loads(ret) print(ret) print(respon)# dump load # 写入文件 (这个不仅可以写常规的数据,还可以将对象写入)class A:name = 'alex'def func(self):print(666)obj = A() f = open('pickle_file', 'wb') pickle.dump(obj, f) f.close()f = open('pickle_file', 'rb') ret = pickle.load(f) print(ret.name) ret.func() f.close()# 03 shelve import shelvef = shelve.open('shelve_file') f['key'] = {'int': 10, 'float': 9.5, 'string': 'Sample data'} # 直接对文件句柄操作,就可以存入数据 f.close()import shelvef1 = shelve.open('shelve_file') existing = f1['key'] # 取出数据的时候也只需要直接用key获取即可,但是如果key不存在会报错 f1.close() print(existing)
9.random模块
''' 整体说明: 01 print(random.random()) # 随机在0~1之间的float 02 print(random.uniform(1,10)) # 1 ~10 浮点型 03 print(random.randint(1,10)) # 1~10 之间的整数 *** 04 print(random.randrange(1,10,2)) # 大于等于1且小于10之间的奇数(2是步长) 05 print(random.choice([1, '23', [4,5]])) # 多选择一 *** 06 print(random.sample([1,'23',[4,5], 'alex'],2)) # 列表元素 任意2个组合 07 random.shuffle(item) # 打乱次序 *** '''''' 需求:生成5位随机验证码 开发思路: 0~9 随机选一个 a~z 随机选一个 两个选一个 ''' import randomdef code():codes = ''for i in range(5):num = str(random.randint(0, 9))char1 = chr(random.randint(97, 122))char2 = chr(random.randint(65, 96))c1 = random.choice([num, char1, char2])codes += c1 # 字符串拼接return codesprint(code())# 说明:chr(code)是根据asscall值获得对应的字符。
转载于:https://www.cnblogs.com/mayugang/p/9980394.html
面向对象进阶和模块初识相关推荐
- JavaSE——面向对象进阶(封装、this、static、代码块、包、权限修饰符、main方法详解)
第2节 面向对象进阶 一.封装与private 概述: 封装的意义在于保护或者防止代码(数据)被我们无意中破坏.保护成员属性,不让类以外的程序直接访问和修改. 封装原则: 隐藏对象的属性和实现细节,仅 ...
- python内置函数面向对象_Pyhton——面向对象进阶二:类的内置函数补充、描述符...
Pyhton--面向对象进阶二: 一.类的内置函数补充 1.isinstance(obj,cls)--检查obj是否是该类的对象 class Hoo: def __init__(self,name,t ...
- 第四十三篇 面向对象进阶2
目录 第四十三篇 面向对象进阶2 一.类的封装 1.封装分为两个层面 2.应用 二.类的property特性 1. BMI(Body Mass Index):身体体质指数 2.装饰器用法(只在Pyth ...
- Java大数据-Week2-Day2面向对象进阶
第二章第三节 面向对象进阶 文章目录 第二章第三节 面向对象进阶 前言 封装 this关键字 静态static 包 包2 权限修饰符 代码块 main方法详解 总结 前言 # 第三章第3节 面向对象进 ...
- python进阶课程目标 学习内容_Python学习教程(Python学习路线):第九天-面向对象进阶...
面向对象进阶 在前面的章节我们已经了解了面向对象的入门知识,知道了如何定义类,如何创建对象以及如何给对象发消息.为了能够更好的使用面向对象编程思想进行程序开发,我们还需要对Python中的面向对象编程 ...
- Day09.面向对象进阶
面向对象进阶 文章目录 面向对象进阶 前言 一. @property装饰器 二. \_\_slots\_\_魔法 三. 静态方法和类方法 四. 类之间的关系 五. 继承和多态 六. 综合案例 案例1: ...
- python进阶路线知乎_Python学习教程(Python学习路线):第九天-面向对象进阶
面向对象进阶 在前面的章节我们已经了解了面向对象的入门知识,知道了如何定义类,如何创建对象以及如何给对象发消息.为了能够更好的使用面向对象编程思想进行程序开发,我们还需要对Python中的面向对象编程 ...
- Day9 :面向对象进阶
文章目录 面向对象进阶 @property装饰器 __slots__魔法 静态方法和类方法 类之间的关系 继承和多态 综合案例 案例1:奥特曼打小怪兽. 案例2:扑克游戏. 案例3:工资结算系统. 面 ...
- Python中级 —— 01面向对象进阶
面向对象进阶 总结.补充(http://blog.csdn.net/fgf00/article/details/52479307) 面向对象高级语法部分 静态方法.类方法.属性方法 类的特殊方法 反射 ...
最新文章
- Cannot find SS.INI file for user *** 解决方法
- jpa映射json_如何使用JPA和Hibernate映射JSON集合
- pjtool用到的数据库----oracle范畴
- svd奇异值分解_传统推荐算法(一)SVD推荐(1)解读奇异值分解
- 概率论 方差公式_概率论与数理统计课程教学、学习基本要求和教学建议
- md5值最大长度_豆长老之比特币-哈希值是什么11月16日分享篇
- 【论文复现】使用RNN进行文本分类
- 如何在C++中调用C程序?(讲的比较清楚)
- 台式计算机没有任务栏,电脑任务栏不见了怎么恢复 电脑任务栏怎么设置并排显示...
- 将solidworks建的机器人模型导入到ros中
- 如何将webp格式转换成png?
- 批量webp格式转换成jpg操作方法
- 根据浏览器的默认语言来切换中英文页面
- RabbitMQ:Plugin configuration unchanged;解决RabbitMQ启动问题,Win10用户中文问题解决
- 一个bat病毒分析(part1)
- python大数据读取分析_python 大数据读取
- 【python10个小实验】2、石头、剪刀、布
- 形容谣言的四字词语_形容会说谎的四字词
- mysql_upgrade --force,MySQL force upgrade
- AJAX框架简笔画风景简单,好看简单的简笔画风景
热门文章
- python实现数据恢复软件_恢复python
- 快手怎么引流做CPA?如何在快手直播上截流操作CPA项目
- 用matlab画一些骚东西,求助matlab大神,学校的课程安排太骚了,我们压根就不用学matlab...
- rm -rf *后怎么办?
- Android 仿今日头条频道管理(下)(GridView之间Item的移动和拖拽)
- 《史上最伟大的交易》读书笔记
- 单片机(keil c51):BCD码转化为二进制(以4位BCD码举例,依此类推)
- 习题3-1至习题3-5
- 人头识别与计数_基于人头检测的人数统计算法研究
- 计算机任务无法结束,简单几步解决win7任务管理器无法结束进程的问题