python(多态,封装)

多态:由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同。

# -*- coding: utf-8 -*-
import abc
class Animal(metaclass=abc.ABCMeta):
#同一类事物:动物
    @abc.abstractmethod
    def talk(self):
        pass
class Cat(Animal):
#动物的形态之一:猫
    def talk(self):
        print('喵喵喵')
class Dog(Animal):
#动物的形态之二:狗
    def talk(self):
        print('汪汪汪')
class Pig(Animal):
#动物的形态之三:猪
    def talk(self):
        print('哼哼哼')

#统一的接口
def talk(self):
    self.talk()
    
#实例化
cat=Cat()
dog=Dog()
pig=Pig()

talk(cat)
talk(dog)
talk(pig)

如上面不同的动物调用相同的函数,实现了不同的功能。

封装

在python中用双下划线开头的方式将属性隐藏起来。(单下划线是开发者之间默认为内部属性,外部不能使用)

以双下划线开头的属性python会自动重命名。

 类的继承具有改变和多态的意义。多态就是类的这两层意义的一个具体的实现机制。

反射

自省也称作反射,这个性质展示了某对象是如何在运行期取得自身信息的。如果传一个对象给你,你可以查出它有什么能力,这是一项强大的特性。

# -*- coding: utf-8 -*-
class people:
    #私有属性
    __star='earth'
    def __init__(self,id,name,age,salary):
        self.id=id
        self.name=name
        self.age=age
        self.salary=salary

    def get_id(self):
        print(self.id)
p=people('bob',969,20,10000)

#asattr()检测对象是否有某属性,方法
print(hasattr(p,'name'))
print(hasattr(p,'get_id'))
#getattr()获取对象属性值,方法地址
print(getattr(p,'name'))
#setattr()添加,修改对象的属性
setattr(p,'hobby','game')
print(p.__dict__)
#delattr()删除对象的属性
#del p.hobby
delattr(p,'hobby')
print(p.__dict__)

反射的意义:如以下不同功能开发者之间,即使某些功能未实现,也不影响其他开发者工作。

 -*- coding: utf-8 -*-
class FtpClient:
    'Ftp客户端功能具体实现'
    def __init__(self,addr):
        print('正在连接服务器%s'%addr)
        self.addr=addr

  

 -*- coding: utf-8 -*-

f1=FtpClient('192.168.1.1')
if hasattr(f1,'get'):
    func_get=getattr(f1,'get')
    func_get()
else:
    print('不存在此方法')
#包含字符串的模块引用
module_1=__import__('C:/lib')
module_1.lib.func()

上面的的这个方法一直定位到顶级模块,下面的方法可以直接到你需要的模块

import importlib
m=importlib.import_module('C:/lib')

类的内置attr属性

# -*- coding: utf-8 -*-
class foo():
    pass
#查看类的内置属性
print(dir(foo))

  

class Foo:
    x=1
    def __init__(self,y):
        self.y=y

    def __getattr__(self, item):
        print('----> from getattr:你找的属性不存在')


    def __setattr__(self, key, value):
        print('----> from setattr')
        # self.key=value #这就无限递归了,你好好想想
        # self.__dict__[key]=value #应该使用它

    def __delattr__(self, item):
        print('----> from delattr')
        # del self.item #无限递归了
        self.__dict__.pop(item)

#__setattr__添加/修改属性会触发它的执行
f1=Foo(10)
print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值
f1.z=3
print(f1.__dict__)

#__delattr__删除属性的时候会触发
f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作
del f1.a
print(f1.__dict__)

#__getattr__只有在使用点调用属性且属性不存在的时候才会触发
f1.xxxxxx

三者的用法演示

二次加工标准类型(包装)

意义:根据我们实际需要改写内置方法与属性。

 @property详细用法
# -*- coding: utf-8 -*-
class List(list): #继承list所有的属性,也可以派生出自己新的,比如append和mid
    def append(self, p_object):
        ' 派生自己的append:加上类型检查'
        if not isinstance(p_object,int):
            raise TypeError('must be int')
        super().append(p_object)

    @property
    def mid(self):
        '新增自己的属性'
        index=len(self)//2
        return self[index]

l=List([1,2,3,4])
print(l)
l.append(5)
print(l)
# l.append('1111111') #报错,必须为int类型

print(l.mid)

#其余的方法都继承list的
l.insert(0,-123)
print(l)
l.clear()
print(l)

授权

授权的关键是__getattr__覆盖方法

如下,重写了write,添加了功能

# -*- coding: utf-8 -*-
import time
class FileHandle:
    def __init__(self,filename,mode='r',encoding='utf-8'):
        self.file=open(filename,mode,encoding=encoding)
    def write(self,line):
        t=time.strftime('%Y-%m-%d %T')
        self.file.write('%s %s' %(t,line))

    def __getattr__(self, item):
        return getattr(self.file,item)

f1=FileHandle('b.txt','w+')
f1.write('你好啊\n')
time.sleep(1)
f1.write('早上好\n')
f1.seek(0)
print(f1.read())
f1.seek(1)
print(f1.read())
f1.close()

  

 

posted on 2020-02-23 22:28  hcy12  阅读(190)  评论(0编辑  收藏  举报

导航