面向对象:进阶
一、类成员修饰符
上一篇中详细介绍了,类成员。类成员可以分为 属性 和 方法。
类成员可以分为两类:
公有成员:到处都可以访问,可以被继承
私有成员:外部不能访问,只能类内部去访问和修改(当修改修改的时候,可以利用内部的方法去调用私有属性去供外部修改),不能被继承。
定义的时候前面加上两个__ 下划线
class Girl:
def __init__(self, name, age):
self.name = name
self.__age = age
def look_age(self):
return self.__age
def modify_age(self):
self.__age += 1
return self.__age
g = Girl('li', 18)
# g.__name # 直接报错,私有成员,外部不能直接访问
print(g.look_age())
print(g.modify_age())
二、metaclass 类祖宗
1. python 中一切皆为对象!
class Foo: pass obj = Foo() print(type(obj)) # 或者使用__class__这个方法 print(type(Foo)) # obj是对象, Foo类的对象 # Foo也是对象,type类的对象
<class '__main__.Foo'>
<class 'type'>
由上可以看出,Foo是type类的对象。
python中创建类的两种写法:
第一种就是上面的代码
第二种使用type来创建,并不常用,第一种写法中默认的object省略了。
def function(self):
print('123')
Foo = type('Foo', (object,), {'func': function})
2. metaclass 定义类
上面的Foo默认是type来创建的,那么我们可以认为,我们所说的类也是一个对象,type类的对象。
我们使用继承,来研究下类的运行过程。
class Mytype(type): # 继承type类
pass
class Foo(metaclass=Mytype): # 默认类都是type创建(继承也是),我们通过metaclass来定义,类由谁来创建。
pass
print(Mytype.__class__)
print(Foo.__class__)
运行结果:
<class 'type'>
<class '__main__.Mytype'>
我们在前面一直说,类()执行,类()自动运行__init__方法,对象()自定运行__call__方法。那现在类也是对象(type的对象)了,那它是怎么运行的。
代码从上而下来执行,让我们来看这个过程。
1. 类是type创建的,创建类时,自动执行type的__init__方法
2. 类() 执行type的__call__方法。(此时类是type的对象,所以执行call)
3. 再调用类中的__new__,类的__init__方法
三、 反射
python中反射,是以字典的形式来查找的,可hash的,查找速度非常快。
1. 反射的由来,程序的输入,一般都是字符串,而类中的方法都是变量名。 没有办法把字符串转换为变量名。
class F:
def __init__(self, name, age):
self.name = name
self.age = age
obj = F()
obj.'name' # 报错,对象中的name是变量,不是字符串
b = 'name'
obj.b # 查找不到,因为是去找b这个变量,类中没有
2. 那我们应该如何利用字符床查找里面变量,进行输出呢。
方法1:__dict__方法
class F:
def __init__(self, name, age):
self.name = name
self.age = age
obj = F('li', 18)
obj.__dict__['name']
方法2:就是反射
反射就是通过字符串来操作类成员。 这四个是python为类提供的内置函数。
getattr() 获取值
hasattr() 判断有没有
setattr() 设置属性
delattr() 删除属性
可针对导入的模块进行反射,导入的模块也是对象。
3. 反射的应用场景
在web框架或其他地方程序,一个类中有很多方法,如果用if来判断,输入,多少个方法,就需要多少个判断。蛋疼死。直接反射。
class Web:
def new(self):
pass
def run(self):
pass
# 还有n多个方法
obj = Web()
inp = input('')
if hasattr(obj, inp):
getattr(obj, inp)() # 几行代码就搞定,用if需要不断的判断
四、单例模式
单例模式从字面上看,只有一个类对象。socket连接
https://www.cnblogs.com/metianzing/p/7719901.html
https://www.cnblogs.com/575dsj/p/7717797.html
五、工厂模式