day07_雷神_面向对象进阶
day07
1.接口类(抽象类)
接口类和抽象类是一种规范,写代码时的规范。
两个思想: 一个是统一接口,一个是定义规则。
最终版本:接口类,抽象类,是一种规范,写代码时的规范 强制性的规定。
from abc import ABCMeta,abstractmethod
class Payrole(metaclass=ABCMeta): # 抽象类或者接口类,制定规范,统一方法名。
@abstractmethod
def pay(self): pass
class QQpay(Payrole):
def pay(self,money):
print('您已经通过qq支付了%s元' %money)
class Alipay(Payrole):
def pay(self, money):
print('您已经通过支付宝支付了%s元' % money)
class Wechatpay(Payrole):
def pay(self, money):
print('您已经通过支付宝支付了%s元' % money)
def pay(obj,money):
obj.pay(money)
# a = QQpay()
# b = Alipay()
c = Wechatpay()
# pay(a,100) # 归一化设计,统一你的支付方式
# pay(b,1200)
pay(c,10000)
2. 多态,鸭子类型
Python默认就支持多态,自带多态,也叫鸭子类型。
python 对于一些相似的方法,不用强制规定,都是约定俗成。
3. 封装
广义封装: 封装到对象中的属性(普通字段),静态字段等。
狭义封装: 私有性封装。
私有:包括私有静态字段(私有静态变量),私有普通字段(私有对象属性),私有方法。
3.1 私有静态字段
class Person:
country = 'China' # 公有静态字段(公有静态变量)
__name = 'oldboy' # 私有静态字段(私有静态变量)
__age = 1000 # 私有静态字段(私有静态变量)
def func1(self):
return self.__name
print(Person.country)
在类的外部不能调用
print(Person.__name)
p1 = Person()
print(p1.__name)
print(Person.__dict__['_Person__name'])
print(Person._Person__name) 虽然可以,但是一定不要这样访问。
在类的内部可以访问
print(p1.func1())
派生类也不可访问父类的私有静态字段。
class God:
__kind = '黄种人' # _God__kind
class Person(God):
country = 'China' # 公有静态字段(公有静态变量)
__name = 'oldboy' # 私有静态字段(私有静态变量)
__age = 1000 # 私有静态字段(私有静态变量)
# def func1(self):
# return self.__name
def func2(self):
return self.__kind # _Person__kind
p1 = Person()
print(p1.func2())
总结: 私有静态字段:类内部可以访问,父类以及类的外部不能访问。
只要类执行,将类的内容加载到内存时,发现有 __变量名 这样的Python解释器自动将__变量名转化成_类名__变量名
类执行,所有的字段和函数名(即内存地址)都会被加载。
3.2 私有普通字段
class Person:
def __init__(self,name,age):
self.name = name # 公有普通字段 (公有普通对象属性)
self.__age = age # 私有普通字段 (私有普通对象属性)
def func1(self):
return self.__age
p1 = Person('alex', 40)
print(p1.name)
print(p1.func1())
私有成员用在哪里?
示例一: 密码加密
class Cipher_encryption:
def __init__(self,username,password):
self.username = username
self.__password = self.__encryption(password)
def __encryption(self,pwd):
'''
加密处理
:param pwd:
:return:
'''
return '%s hao123' % pwd
user1 = Cipher_encryption('alex', 'alexsb')
print(user1.username)
# print(user1.password)
print(user1.__dict__)
对于只想让类内部使用的成员,要设置成私有成员。
示例二:
class A:
a = 1
b = 2
def __init__(self):
c = 666
a1 = A()
a1.a = 333
a1.b = 555
print(a1.a,a1.b,a1.c)
c = 666 不在a1对象的内存地址中,虽然执行了__init__方法,但是没有self.c = 666.
示例三: 类中遇到双下线加变量,就自动改名字。
class A:
def __init__(self):
self.__func()
def __func(self):
print("in A")
class B(A):
def __func(self):
print("in B")
b = B()
这时候输出的是A,因为__func函数改名字了。
4. 字段,方法,普通方法,静态方法,类方法,属性
4.1 普通方法
一般由对象调用。
4.2 属性
@property
class People:
def __init__(self, name, weight, height):
self.name=name
self.__weight=weight
self.__height=height
@property
def bmi(self):
return self.__weight / self.__height**2
p1 = People('天', 95,1.83)
print(p1.bmi)
# property 属性将你的一些方法伪装成属性,虽然在代码上没有什么提高,让其看起来更合乎情理.
@ property 下的@方法.setter,修改
class Goods:
def __init__(self,name,origin_price,discount):
self.name = name
self.__origin_price = origin_price
self.__discount = discount
@property
def price(self):
return self.__origin_price*self.__discount
@price.setter
def price(self,new_price):
self.__origin_price = new_price
p1 = Goods('apple',5,0.8)
print(p1.price)
p1.price = 8
print(p1.price)
@ property 下的@方法.deleter,删除
class People:
def __init__(self, name, age, sex):
self.name = name
self.__age = age
self.__sex = sex
@property
def age(self):
return self.__age
@age.setter
def age(self,new_age):
if type(new_age) == int:
self.__age = new_age
else:
print('请输入一个整数')
@age.deleter
def age(self):
print(666)
p1 = People('天', 28, '男')
print(p1.name)
p1.name = '地'
print(p1.name)
print(p1.age) # p1.age 触发 @property装饰的方法
p1.age = '1234' # p1.age = '1234' 触发 @age.setter装饰的方法
print(p1.age)
del p1.age # del p1.age 触发 @age.deleter装饰的方法
4.3 类方法
一般是由类名调用.有些情况,对于类内部的方法,无需对象直接调用,而类名直接调用即可。
@classmethod
class Goods:
__discount = 0.8
def __init__(self,name,origin_price):
self.name = name
self.__origin_price = origin_price
@property
def price(self):
return self.__origin_price * Goods.__discount
@classmethod
def discount(cls,new_discount):
Goods.__discount = new_discount
p1 = Goods('apple',5)
print(p1.price)
# p1.discount(0.85)
Goods.discount(0.85)
print(p1.price)
4.4 静态方法
不需要传入对象,和类名,直接调用即可.
class A:
def __init__(self):
pass
@staticmethod
def login(username,password):
print(username,password)
A.login('alex',123)
5. 其他成员及方法
isinstance() 对象是否属于这个类,或者这个类血缘关系.
class C: pass
class A(C): pass
class B(A): pass
abj = B()
print(isinstance(abj,B)) #True
print(isinstance(abj,A)) #True
print(isinstance(abj,C)) #True
issubclass() 判断 第一类是第二个类的后代.True
class C: pass
class A: pass
class B(A,C): pass
print(issubclass(A,B)) #False
print(issubclass(B,C)) #True
反射:非常重要。!!
01.类中的反射:
这个方法是用dict方法,通过字典的key来查询。
class A:
role = 'Teacher'
def func(self):
print(666)
msg = input('>>>')
print(A.role)
print(A.__dict__[msg])
getattr方法
getattr(A,msg) # *****
getattr(A,msg)(111) # 通过字符串 去到 类名 中获取对应的值.
print(getattr(A,msg))
hasattr() *****
print(hasattr(A,msg))
if hasattr(A,msg):
print(getattr(A,msg))
else:
print('不存在此值')
setattr() 增加或者修改 **
setattr(A,'name','alex')
setattr(A,'role','student')
print(A.__dict__)
delattr(A,'role') # 删除*
print(A.__dict__)
02.对象中的反射
在python 中一切皆对象,凡是通过 什么.什么 通过 反射都能取到
class A:
role = 'Teacher'
def __init__(self, name, age):
self.name = name
self.age = age
a1 = A('太白', 18)
print(hasattr(a1,'name')) True
print(hasattr(a1,'sex')) False
print(getattr(a1, 'role')) Teacher
03. 模块中
一个模块就是一个文件
import time
print(time.time())
print(getattr(time,'time'))
print(getattr(time,'time')())
oldboy模块
def func():
name = 'alexsb'
print('此函数完成的是打印666功能')
class A:
role = 'Teacher'
def func1(self):
print(666)
反射示例:
import oldboy
print(getattr(oldboy,'func'))
getattr(oldboy,'func')()
方式一
print(getattr(oldboy,'A'))
print(getattr(oldboy,'A').role)
getattr(oldboy,'A').func1(11)
方式二
print(getattr(getattr(oldboy,'A'),'role'))
04. 当前模块中
def login():
print(666)
msg = input('>>>')
import sys
getattr(sys.modules[__name__],msg)()
print(globals()) #{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001B465F3A3C8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/PycharmProjects/oldboy/day07/day07/07 其他成员及方法.py', '__cached__': None, 'login': <function login at 0x000001B465E31E18>, 'msg': 'login', 'sys': <module 'sys' (built-in)>}
print(locals())
print(dir()) # ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'login', 'msg', 'sys']
print(__name__) #__main__
其他方法:
01. __len __
class A:
def __init__(self):
self.a = 1
self.b = 2
def __len__(self):
return len(self.__dict__)
a = A()
print(len(a))
02. __hash __
class A:
def __init__(self):
self.a = 1
self.b = 2
def __hash__(self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))
03. __ str__
类中如有__str__方法,print(对象),str(a) print('%s' % a),打印该对象时,默认输出该方法的返回值。
class A:
def __init__(self):
pass
def __str__(self):
return '太白'
a = A()
print(a,type(a)) 太白 <class '__main__.A'>
print(str(a),type(str(a))) 太白 <class 'str'>
print('%s' % a) 太白
04. __ repr __
和str一样
class A:
def __init__(self):
pass
def __repr__(self):
return '太白'
a = A()
print(a)
print(repr(a))
print('%r'%a)
05. __call __
对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
06. __eq __
07. __ del__
析构方法,当对象在内存中被释放时,自动触发执行。
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
08. __ new__
实例化对象的时候自动触发。
单例模式:
class A:
__instance = None
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
obj = object.__new__(cls)
cls.__instance = obj
return cls.__instance
09. item系列
class Foo:
def __init__(self,name):
self.name=name
def __getitem__(self, item):
print(self.__dict__[item])
def __setitem__(self, key, value):
print(key,value)
self.__dict__[key]=value
def __delitem__(self, key):
print('del obj[key]时,我执行')
# self.__dict__.pop(key)
f1 = Foo('sb')
# f1['name'] # 对对象进行字典式的查询操作 触发 __getitem__
# f1['age'] = 18 # 对对象进行字典式的更改 触发 __setitem__
f1['age1']=19
# del f1.age1
del f1['age'] # 对对象进行字典式的del删除 触发 __delitem__
f1['name']='alex'
print(f1.__dict__)
day07_雷神_面向对象进阶的更多相关文章
- python基础_面向对象进阶
@property装饰器 之前我们讨论过Python中属性和方法访问权限的问题,虽然我们不建议将属性设置为私有的,但是如果直接将属性暴露给外界也是有问题的,比如我们没有办法检查赋给属性的值是否有效.我 ...
- day06_雷神_面向对象初识
day_06 递归函数 自己用自己.一般递归100多次,都没有解决的问题,放弃递归. count = 0 def func1(): global count count += 1 print(coun ...
- day05_雷神_函数进阶
#day05 1.迭代器 1.1可迭代对象 str,list,tuple,dict,set,range,文件句柄 等都是可迭代对象 第一种方法:在该对象中,含有__iter__方法的就是可迭代对象,遵 ...
- python进阶_浅谈面向对象进阶
python进阶_浅谈面向对象进阶 学了面向对象三大特性继承,多态,封装.今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数. 一.isinstance和issubclass class F ...
- day26、面向对象进阶:多态、封装、反射
一.多态 什么是多态: 类的继承有两层意义:1.改变 2.扩展 多态就是类的这两层意义的一个具体的实现机. 即:调用不同类实例化的对象,下的相同的方法,实现的过程不一样 python中的标准类型就是多 ...
- Python开发【第七篇】:面向对象 和 python面向对象进阶篇(下)
Python开发[第七篇]:面向对象 详见:<Python之路[第五篇]:面向对象及相关> python 面向对象(进阶篇) 上一篇<Python 面向对象(初级篇)> ...
- python_面向对象进阶(7)
第1章 面向对象特性—继承(补充) 1.1 接口类.抽象类介绍 1.2 接口类 1.3 接口类应用过程 1.3.1 第一版:完成多种支付方式接口 1.3.2 第二版: 归一化设计,统一支付方式 1.3 ...
- Py-多态,封装,反射,描述符,包装标准类型,面向对象进阶
多态: 对象可以通过他们共同的属性和动作来访问,而不需要考虑他们的类多态是继承的应用 class H2o: def __init__(self,temp): self.temp=temp def ht ...
- Python全栈开发【面向对象进阶】
Python全栈开发[面向对象进阶] 本节内容: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__geta ...
随机推荐
- 如何判断来访的IP是否是百度蜘蛛ip?
网站日志是可以真实体现网站的状态,通过网站日志我们可以清楚的看到网站每天有多少访客,每天有多少蜘蛛来抓取网站的数据,哪些数据被蜘蛛抓取了.哪些页面在请求数据的时候发现了错误.这些都是可以通过状态码来进 ...
- BZOJ1123或洛谷3469 [POI2008]BLO-Blockade
BZOJ原题链接 洛谷原题链接 若第\(i\)个点不是割点,那么只有这个点单独形成一个连通块,其它点依旧连通,则答案为\(2\times (n-1)\). 若第\(i\)个点是割点,那么去掉这个点相关 ...
- C++ 的虚析构函数
当一个基类的指针指向一个派生类的对象,并用该基类的指针去删除或者析构派生类对象时,如果基类的析构函数不是声明为虚函数,那么在析构时基类的析构函数将会被直接调用,派生类的析构函数应为没被调用而导致内存泄 ...
- Linux中处理字符串
获取字符串长度: ${#字符串变量名} 截取子串: 1. expr substr 字符串 起始位置 截取长度 2. 命令输出 | cut -c 起始位置-结束位置 命令输出 | cut -c &quo ...
- Netty 源码(一)Netty 组件简介
Netty 源码(一)Netty 组件简介 Netty 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.Netty 架构 Core: ...
- 对象回收过程?线程池执行过程? map原理?集合类关系?synchronized 和 volatile ? 同一个类的方法事务传播控制还有作用吗?java 锁
1. 对象回收过程? 可达性分析算法: 如果一个对象从 GC Roots 不可达时,则证明此对象不可用. 通过一系列称为GC ROOTS的对象作为起点,从这些起点往下搜索,搜索走过的路径 称为引用链 ...
- mysql 5.7.10 下互为主备配置
mysql安装方法这里就不在介绍,网上有很多教程 环境介绍: A主机: win2008_x64+mysql5.7.10 64位,ip192.168.7.180 B主机: win2008_x64+mys ...
- Zxing2.1扫描取景框变形问题解决
修改竖屏扫描的贴子,2.0之前的都很适用.可是到了2.1,有些贴子的做法可以将扫描框改为竖屏,但是取景框里扫描到的东西是变形的(扁的),本人仔细研究一番,终于解决了这个问题,下面贴出解决办法: 1.修 ...
- spring cloud 组件图
spring cloud 提供了一套微服务的框架. 上图就是微服务一些常用的组件. 1.EureKa 实现服务的注册和发现. 2.Ribbon 实现服务的调用(客户端实现负载均衡) 3.Feign 实 ...
- Le Chapitre IX
Je crois qu'il profita, pour son évasion[evazjɔ̃]逃跑, d'une migration d'oiseaux sauvages[sovaʒ]未驯化的. ...