面向对象:进阶

一、类成员修饰符

  上一篇中详细介绍了,类成员。类成员可以分为 属性 和 方法。

  类成员可以分为两类:

      公有成员:到处都可以访问,可以被继承

      私有成员:外部不能访问,只能类内部去访问和修改(当修改修改的时候,可以利用内部的方法去调用私有属性去供外部修改),不能被继承。

           定义的时候前面加上两个__ 下划线

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

 

五、工厂模式

 

posted @ 2018-05-01 17:08  娄先生  阅读(180)  评论(0编辑  收藏  举报
levels of contents