码迷,mamicode.com
首页 > 编程语言 > 详细

python 课堂15 面向对象3 内部方法,类的定制

时间:2018-08-09 01:13:50      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:time   就会   使用字符串   创建对象   定义   creat   删除对象   需要   目标   

面向对象 3 高级用法

绑定方法:

绑定方法,非绑定方法
绑定方法: 对象绑定,类绑定 @ classmethod
非绑定 @ staticmethod

class Foo:
    # 没有装饰器的函数,参数自动传入对象,和对象绑定,是对象绑定方法
    def func1(self):
        print(self)
    # 使用classmethod装饰,自动传入类,和类绑定,是类的绑定方法。
    @ classmethod
    def func2(cls):
        print(cls)
    # 使用staticmethod装饰,不自动传入任何东西,就是普通方法
    @ staticmethod
    def func3():
        print(‘普通工具类‘)
f = Foo()
f.func1()   # <__main__.Foo object at 0x000001DFFED06278>
f.func2()   # <class ‘__main__.Foo‘>
f.func3()   # 普通工具类

绑定对象方法,绑定类方法,非绑定方法的使用

import db
import time,hashlib
class People:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def info(self):
        print(‘my name is %s age is %s‘%(self.name,self.age))

    # 函数依赖类的传入
    @classmethod
    def creat_obj(cls):
        obj = cls(db.name,db.age)
        return obj

    # 独立的工具
    @staticmethod
    def creat_id():
        hs = hashlib.md5(str(time.time()).encode(‘utf8‘))
        return hs.hexdigest()

p1 = People(‘ql‘,22)
p1.info()
p2 = People.creat_obj()  # 使用类方法直接创建对象
p2.info()
id = p2.creat_id()
print(id)

property

class People:
    def __init__(self,name):
        self.__name = name

    # 将方法伪装为属性,调用时不需要加括号。
    @ property   # name = property(name)
    def name(self):
        return self.__name

    # property 伪装成属性后,如果被赋值,将触发
    @ name.setter  # name = name.setter(name) ==>name.name.__setter__()
    def name(self,name):
        self.__name = name
        return self.__name

    # property 伪装成属性后,如果被删除,将触发
    @ name.deleter # 删除name 触发
    def name(self):
        print(‘不准删name‘)

p = People(‘qianlei‘)
p.name = ‘qianlei123‘
print(p.name)
将name 封装,看似直接调用name,其实该name 是方法,可以对查看名称进行定制。

反射

反射就是使用字符串来作为属性名,去调用。

class People:
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def info(self):
        print(‘my name is %s age is %s‘%(self.name,self.age))

p = People(‘qianlei‘,22)
调用属性时,如果接收用户输入,将字符串作为属性名,则无法调用。
想调用可以使用字典 p.__dict__[‘name‘]
python 还提供了简单的解决办法
print(p.name)

反射 hasattr() getattr() setattr() delattr()

print(hasattr(p,‘name‘))
print(getattr(p,‘name‘,None)) # 第三个参数为默认返回,如果没有该属性默认返回值。
print(getattr(p,‘name1‘,None))
setattr(p,‘sex‘,‘male‘)
print(getattr(p,‘sex‘))
delattr(p,‘sex‘)
print(getattr(p,‘sex‘,‘没有这个属性‘))

反射应用

class service():

    def run(self):
        while True:
            res = input(‘>>>>‘).strip()
            # if hasattr(self,res):  # 先判断是否有这个属性
            #     func = getattr(self,res)  # 获取属性
            #     func()  # 运行属性
            mes_list = res.split()
            if hasattr(self,mes_list[0]):
                func = getattr(self,mes_list[0])
                func(mes_list[1])

    def get(self,mes):
        print(‘get.......‘,mes)
    def put(self,mes):
        print(‘put.........‘,mes)

s = service()
s.run()

__call__ __new__ __str__

__call__ : 将类的实例变成可以调用的对象,实例+(),运行

class Foo:
    def __call__(self, *args, **kwargs):
        print(‘this is call func‘)
        print(args)
        print(kwargs)
f = Foo()
f(‘a‘, b=1)
===》this is call func
===》(‘a‘,)
===》{‘b‘: 1}

__new__ : 类实例化时自动调用,可以定制实例化。

 class Foo:
    def __new__(cls, *args, **kwargs):
        print(‘this is new func‘)
        print(args)
        print(kwargs)
f = Foo(‘a‘, b=1)
===》this is new func
===》(‘a‘,)
===》{‘b‘: 1}

__str__ :打印实例时调用。

 class Foo:
    def __str__(self):
        return ‘this is str‘
f = Foo()
print(f)
===》this is str

_getattr_ __setattr__ __delattr__

定制对象获取设置删除属性方法:_getattr_() _setattr_() _delattr_()
_getattribut_():对象调用属性时激活,但是当抛出AttributError() 则激活_getattr_(),需要自己设置。
_getattr_() :对象调用属性时没有对应属性,则激活_getattr_()
_setattr_() :对象设置属性时激活运行,并且返回该方法的返回值。可以规定修改属性时返回什么。
_delattr_():对象删除属性时激活运行,并且返回该方法的返回值。可以规定删除属性时返回什么。

class Test():
    def __init__(self,name):
        self.name=name

    def __getattr__(self, item):
        print(‘getattr is running %s was not find ‘%item)

    def __setattr__(self, key, value):
        print(‘setattr is running %s is seting‘%key)
        # self.key=value#这个方法会调用自己,因为方法本身就是添加属性,无限递归
        self.__dict__[key]=value#设置时需要使用对象字典

    def __delattr__(self, item):
        print(‘delattr is running %s is del‘%item)
        del self.__dict__[item]#删除对象字典元素,否则会无限递归。

t=Test(‘tes‘)   #只要有属性生成或变动就会触发__setattr__
print(t.erro_name)#调用不存在的属性 就会触发 __getattr__()方法
t.age=20    #只要有属性生成就会触发__setattr__
print(t.__dict__)
del t.age#只要删除属性就会触发__delattr__
print(t.__dict__)

二次加工标准模型

使用继承,定制自己的类。
就是使用继承对标准模型,进行个性化定制,
添加自己的需求,并且还可以使用标准模型的功能。
例如对列表进行定制,实例化列表时,要求必须传入字符串。

class Mylist(list):
    def __init__(self, strtype):
        if isinstance(strtype, str):
            super().append(strtype)
        else:
            print(‘必须传入字符串‘)
# 这里必须传入字符串
l = Mylist(‘123‘)
print(l)
# 还可以使用原来的功能。
l.append(‘abc‘)
print(l)

授权:

利用目标类的实例,去调用目标类的方法。相当于利用目标类的实例授权目标类的方法。
1、先给类中添加目标类的实例
2、需要调用目标类中的方法时,使用__getattr__()去转接目标类的方法。
3、需要修改目标类的方法时,则利用目标类的实例给出对应的方法,并包装修改。

import time
class file_io():
    def __init__(self,filename,mode,encoding=‘utf-8‘):
        self.file=open(filename,mode,encoding=encoding)#给实例属性添加个open()实例,利用这个实例给自己添加open()中的方法。
        self.mode=mode
        self.encoding=encoding
    # 自己定义write()方法,本质上还是调用文件对象的write()方法,给予了定制功能
    def write(self,neirong):
        #利用open()实例file,授权write方法,定制包装自己的write()方法。
        #每次写入内容时添加时间。
        t = time.strftime(‘%Y-%m-%d %X‘)
        res=‘%s %s‘%(t,neirong)
        return self.file.write(res)#返回文件句柄中的write()
    # 调用本类没有的方法时,去对象的类中去找。。
    def __getattr__(self, item):
        #利用__getattr__()方法去授权对象调用open()的实例file,中的各种方法。
        return getattr(self.file,item)#授权f对象使用标准文件句柄中的各种属性。

f=file_io(‘test.txt‘,‘w+‘)
f.file.write(‘None\n‘)#f对象调用自己的属性file,file句柄中有write()方法
f.write(‘qwe\n‘)       #调用定制的write()方法 
f.write(‘sdad\n‘)
f.seek(0)
print(f.read())#f中没有read()方法,所以触发__getattr__(),返回文件句柄本身提供的read()
f.close()

python 课堂15 面向对象3 内部方法,类的定制

标签:time   就会   使用字符串   创建对象   定义   creat   删除对象   需要   目标   

原文地址:https://www.cnblogs.com/qianduoduo123/p/9446535.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!