1.接口类和抽象类
一种规范,写代码时的规范
from abc import ABCMeta, abstractmethod
class IStream(metaclass=ABCMeta):
@abstractmethod
def read(self, data):
print('read super method')
@abstractmethod
def write(self, data):
print('write super method')
class SocketStream(IStream):
def read(self, data):
print('read sub method')
def write(self, data):
print('write sub method')
p = SocketStream()
p.read(1)
python-对于一些相似的方法,不用前置规定,都是约定俗成。
具有共同属性或方法就互为“鸭子类型”
2.封装
class Person:
country = 'China'
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person('morgan', 12) #封装
# (广义封装)封装到对象中的属性就是一种封装
# (狭义封装)私有封装
2.1私有性封装
- 私有静态字段(私有静态变量)
- 私有普通字段(私有对象属性)
- 私有方法
2.1.1私有静态字段
class Person:
country = 'China' # 公有静态变量
__name = 'morgan' # 私有静态字段
def func(self):
print(Person.__name)
class People(Person):
def func1(self): pass
print(Person.country)
print(Person.__name) #获取不到这个私有变量值
p1 = Person()
p1.__name #获取不到这个私有变量值
p2 = People()
p2.__name #子类中也不能访问父类的私有静态字段
- 私有静态字段:类内部可以访问,父类以及类的外部不能访问。
- 机密敏感数据要设置成私有的。
- 只要类执行,加载将类的内容加载到内存时,发现有“ 变量名”, 这样的python解释器自动将转化成“_类名变量名”
2.1.2.私有方法
2.1.2.1方法的分类:
- 普通方法:一般是由对象调用
- @property属性:将一些方法伪装成属性,让他看起来更合乎情理,虽然代码没有任何提高。
class Person:
def __init__(self, name, age):
self.name = name
self.__age = age
@property
def age(self):
return self.__age
@age.setter
def age(self, new_age):
self.__age = new_age
print(new_age)
@age.deleter
def age(self):
print(777)
p1 = Person('morgan', 29)
p1.age = 18
del p1.age #配合上面deleter装饰器使用
2.1.2.2类方法
一般是由类名调用,有些情况,对于类内部的方法,无需对象直接调用,而类名直接调用。
class Goods:
__discount = 0.8
def __init__(self, product, price, discount):
self.product = product
self.__price = price
self.__discount = discount
@property
def price(self):
return self.__price*self.__discount
@price.setter
def price(self, new_price):
print(self.__price = new_price)
@classmethod
def discount(cls, new_discount):
Goods.__discount = new_discount
p1 = Goods()
Goods.discount(0.85)
print(p1.price)
2.1.2.3静态方法:
不需要传入类名和对象直接调用即可。
class A:
def __init__(self):
pass
@statiscmethod
def login(username, pwd):
print(username, pwd)
A.login('morgan', 123)
3.反射与自省
- In other words, introspection(自省) is passive, and reflection is active.
- python的反射,它的核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
自省
- dir()
- isinstance() #对象是否属于这个类,或者这个类的派生类。
- issubclass() #判断第一个类是第二个类的后代。
反射:
- getattr(实例或模块名,参数名) #获取类变量
- hasattr(实例或模块名,参数名) #通过字符串获取对应的值是否存在
- setattr(实例或模块名,参数名, 参数值) #增加或修改
- delattr(实例或模块名,参数名)
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def test(self, new_discount):
print(new_discount)
def age(self):
print(self.age)
p = Person('morgan', 19)
print(getattr(p, 'age')) #输出:19
在python中一切皆对象,凡是通过。
- 类的装饰器—回去看
- 反射应用场景
_len_
_call_
_item_
_new_
class Foo:
def __init__(self,name):
self.name=name
def __getitem__(self, item):
print(self.__dict__[item])
def __setitem__(self, key, value):
self.__dict__[key]=value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key时,我执行')
self.__dict__.pop(item)
f1=Foo('sb')
f1['age']=18
f1['age1']=19
f1['name']='morgan'
print(f1.__dict__) #输出:{'name': 'morgan', 'age': 18, 'age1': 19}
设计模式—单例设计模式
class A:
__instance = None
def __new__(cls, *args, **kwargs)
if cls.__instance is None:
obj = object.__new__(cls)
cls.__instance = obj
return cls.__instance
a = A()
b = A()
print(a, b) #a,b地址一样