python学习(十六)——多态、封装、反射、、动态导入模块、类内置attr方法

一、多态

# 不同的实例调用同样的方法,产生不同的结果
# 多态来自继承
class H2O:
    def __init__(self,name,temperature):
        self.name=name
        self.temperature=temperature
    def turn_ice(self):
        if self.temperature < 0:
            print('[%s]温度太低结冰了' %self.name)
        elif self.temperature > 0 and self.temperature < 100:
            print('[%s]液化成水' %self.name)
        elif self.temperature > 100:
            print('[%s]温度太高变成了水蒸气' %self.name)
    def aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(self):
        pass

class Water(H2O):
    pass
class Ice(H2O):
    pass
class Steam(H2O):
    pass

w1=Water('水',25)
i1=Ice('冰',-20)
s1=Steam('蒸汽',3000)

# w1.turn_ice()
# i1.turn_ice()
# s1.turn_ice()

def func(obj):
    obj.turn_ice()

func(w1)  #---->w1.turn_ice()
func(i1)  #---->i1.turn_ice()
# def func(obj):
#     obj.turn_ice()
#
# func(w1)
# func(i1)
# func(s1)

二、封装

# 第一层封装:类就是麻袋,本身是一种封装
# 第二层封装: _ (单下划线)对外部隐藏,只能内部使用--- 仅仅是约定,仍然可以访问到
#             __ (双下划线)python会对其重命名为--- _People__star
# 第三层封装:只在内部使用,外部无法调用到,并且提供一个接口

#----------------------------封装一--------------------------------
class People:
    __star='earth111111111111'
    __star1='earth111111111111'
    __star2='earth111111111111'
    __star3='earth111111111111'
    def __init__(self,id,name,age,salary):
        print('----->',self.__star)
        self.id=id
        self.name=name
        self.age=age
        self.salary=salary

    def get_id(self):
        print('我是私有方法啊,我找到的id是[%s]' %self.id)

    #访问函数
    def get_star(self):
        print(self.__star)



p1=People('123123123123','alex','18',100000000)
# print(p1.__star)
print(People.__dict__)
# print(p1.__star)
print(p1._People__star)
#
# p1.get_star()
p1.get_star()

#----------------------------封装示例2------------------------------------------
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width       # 最开始的时候不要用下划线开头
        self.__length=length
        self.__high=high

    def tell_area(self): # 此时我们想求的是面积 --接口函数(不推荐)
        return self.__width * self.__length *self.__high

    def tell_width(self):
        return self.__width


r1=Room('卫生间','alex',100,100,10000)

# arear=r1.__width * r1.__length
print(r1.tell_area())

三、反射\自省

1、四个自省函数

# 类和对象都适用
# 判断object中有没有一个叫name字符串对应的方法或函数
hasattr(object, name)

# 找名字或者方法函数,default是判断为False时输出信息
hasattr(object, name, default)

# 修改
setattr(x, y, v)

# 删除
delattr(x, y)


class BlackMedium:
    feture='Ugly'
    def __init__(self,name,addr):
        self.name=name
        self.addr=addr

    def sell_hourse(self):
        print('【%s】 正在卖房子' %self.name)

    def rent_hourse(self):
        print('【%s】 正在租房子' % self.name)

b1=BlackMedium('abc','rb')
print(hasattr(b1,'name'))

2、反射的使用

# 可插拔式设计
#--------------------------使用者------------------------------
from ftp_client import FtpClient

f1=FtpClient('1.1.1.1')
# f1.put()

if hasattr(f1,'put'):
    func_get=getattr(f1,'put')
    func_get()
else:
    print('其他的逻辑')

#-------------------------客户端-------------------------------
class FtpClient:
    'ftp客户端,但是还没有实现具体的功能'
    def __init__(self,addr):
        print('正在连接服务器[%s]' %addr)
        self.addr=addr
# 后面实现的功能
    # def put(self):
    #     print('正在上传文件')

三、动态导入模块

module_t=__import__('m1.t') # 导入模块只导入了m1
print(module_t)
module_t.t.test1()

import  importlib
m=importlib.import_module('m1.t') #导入例如m1.t
print(m)
m.test1()
m._test2()

#---------------------当导入全部时,_开头的不能导入---------------------
from m1.t import *
# from m1.t import test1,_test2

test1()
_test2()  #出错

四、类的内置attr属性

# 不重写就用默认的,重写就用重写的
class Foo:
    x = 1
    def __init__(self, y):
        self.y = y

    def __getattr__(self, item):   # 用处较多
        print('执行__getattr__')
    
    def __delattr__(self, item):
        print('删除操作')
        self.__dict.pop(item)

    def __setattr__(self, key, value):
        print('__setattr__执行')
        # self.key = value    无限递归,错误
        self.__dict__[key] = value


f1 = Foo(10)
# 调用一个不存在的属性时执行
print(f1.y)
print(getattr(f1, 'y')) # len(str)--->str.__len__()
f1.asdasd # 执行__getattr__
# 删除时执行
del f1.y

print(f1.__dict__)# 添加成功

五、二次加工标准类型(包装、授权)

#------------------------------包装------------------------------------
class List(list):
    def append(self, p_object):
        if type(p_object) is str:
            # self.append(p_object)
            super().append(p_object)
        else:
            print('只能添加字符串类型')

    def show_midlle(self):
        mid_index=int(len(self)/2)
        return self[mid_index]


# l2=list('hell oworld')
# print(l2,type(l2))

l1=List('helloworld')
# print(l1,type(l1))
# print(l1.show_midlle())
l1.append(1111111111111111111111)
l1.append('SB')
print(l1)

#-----------------------------------授权--------------------------------
# 通过__getattribute__实现
import time
class FileHandle:
    def __init__(self,filename,mode='r',encoding='utf-8'):
        # self.filename=filename
        self.file=open(filename,mode,encoding=encoding)
        self.mode=mode
        self.encoding=encoding
    def write(self,line):
        print('------------>',line)
        t=time.strftime('%Y-%m-%d %X')
        self.file.write('%s %s' %(t,line))

    def __getattr__(self, item):
        # print(item,type(item))
        # self.file.read
        return getattr(self.file,item)

f1=FileHandle('a.txt','w+')
# print(f1.file)
# print(f1.__dict__)
# print('==>',f1.read) #触发__getattr__
# print(f1.write)
f1.write('1111111111111111\n')
f1.write('cpu负载过高\n')
f1.write('内存剩余不足\n')
f1.write('硬盘剩余不足\n')
# f1.seek(0)
# print('--->',f1.read())

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值