Python 魔术方法

#常用魔术方法
#魔术方法不需要用户调用,会在特定的时刻自动执行的方法就是魔术方法

#__init__魔术方法  初始化魔术方法
'''
触发时机:做出对象,对象初始化的时候触发
功能:为对象添加成员[肯定不会添加到类中]
参数:至少一个self接受对象,其他根据情况添加
返回值:无
'''

import random
class Human:
    #属性
    age = 1
    color = 'yellow'

    #方法
    def __init__(self,diyname):
        #为对象添加成员
        #print(self)
        self.hair = '自然卷'
        self.name = 'diyname'
        #随机产生性别
        if random.randrange(0,2) == 1:
            self.sex = ''
        else:
            self.sex = ''

    def eat(self):
        print('吃饭')

    def drink(self):
        print('喝水')

#实例化对象
zw = Human('旺旺')
print(zw.__dict__)

print(Human.__dict__)


#__new__ 构造方法
'''
触发时机:创建对象的时候触发(在语法上和init的触发相同)
功能:控制对象的创建过程
参数:至少一个cls接受当前的类,其他根据情况决定
返回值:有返回值也可以没有(这里的返回值通常返回对象)
'''

class Human:
    #属性
    age = 18
    sex = 'man'

    #方法
    def __new__(cls,diyname):
        #print('new方法被触发')
        print(cls)
        return object.__new__(cls)

    def __init__(self,diyname):
        pass

    def sleep(self):
        print('睡觉')

    def eat(self):
        print('吃饭')

#实例化对象
sy = Human('') #1.创建对象(new)  2.对对象进行初始化操作(init)
print(sy)


#单例设计模式

class WangYingsong:
    #属性
    color = 'yellow'
    age = 27
    name = '应松'
    #声明了一个类成员属性用于保存创建的对象
    obj = None

    #方法
    def __new__(cls):

        #检测是否已经制作过对象
        if cls.obj == None:#没有做过对象
            #实例化对象(存入当前类中)
            cls.obj = object.__new__(cls)
            return cls.obj
        else:#做过对象,直接将类中保存的对象返回
            return cls.obj

    def study(self):
        print('好好学习天天向上')

    def eat(self):
        print('吃饭')

#实例化对象1
ys1 = WangYingsong()
print(ys1)

#实例化对象2
ys2 = WangYingsong()
print(ys2)

#实例化对象3
ys3 = WangYingsong()
print(ys3)


#del魔术方法
'''
触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.对象的所有变量被del的时候]
功能:处理对象使用完毕时候的成员或者资源的回收
参数:一个self接受对象
返回值:无
'''
class Human:
    #属性
    money = 1000
    sex = 'man'
    age = 18
    name = '小松松'

    #方法
    def eat(self):
        print('吃饭')

    def drink(self):
        print('喝水')

    #del魔术方法  析构方法
    def __del__(self):
        print('del方法被触发')

#实例化对象
ss = Human()
#将对象赋值给另外一个变量
yy = ss
print(ss)
print('----------')

del ss
del yy

print('----------')


#文件读取操作
'''
1.打开文件
2.读取文件
3.关闭文件
'''

'''
fp = open('11.txt','r')
fp.read()
fp.close()
'''
class ReadFile:

    #打开文件(构造)
    def __init__(self,filename):
        #打开文件将文件io对象保存在对象成员
        self.fp = open(filename,'r')

    #读取文件
    def fread(self):
        return self.fp.read()

    #关闭文件(析构)
    def __del__(self):
        print('关闭文件操作')
        self.fp.close()

#实例化对象
one = ReadFile('11.txt')
txt = one.fread()
print(txt)


#call魔术方法
'''
触发时机:把对象当做函数调用的时候自动触发
功能:简化操作
参数:至少一个self接受当前对象,其他参数根据程序决定
返回值:根据程序决定
'''
class Human:
    #属性
    sex = 'man'
    age = 18
    color = 'yellow'
    #方法
    def eat(self):
        print('吃饭')

    def sleep(self):
        print('睡觉')

    def __call__(self):
        print('call魔术方法被触发')

#实例化对象
bb = Human()
print(bb)
#把对象当做函数调用的时候
bb()


#做蛋糕的类

class MakeCake:
    #和面
    def huomian(self):
        print('和面操作')
    #发酵
    def fajiao(self):
        print('发酵操作')
    #烘烤
    def hongkao(self):
        print('烘烤操作')
    #切形状
    def zaoxing(self):
        print('切形状')
    #抹奶油
    def monaiyou(self):
        print('抹奶油操作')

    #打包
    def dabao(self):
        print('打包操作')
        return '完整的盒装蛋糕'

    #获取蛋糕的方法
    def __call__(self,who):
        print('制作者:',who)
        self.huomian()
        self.fajiao()
        self.hongkao()
        self.zaoxing()
        self.monaiyou()
        result = self.dabao()

        return result

#实例化对象
mc = MakeCake()

#用户获取蛋糕
r = mc('大厨')
print(r)


#len魔术方法
'''
触发时机:使用len(对象)的时候自动触发
功能:用于检测对象中或者类中某个内容的个数
参数:只有一个参数self接受当前对象
返回值:必须返回整型
'''
class Human:
    #属性
    sex = 'man'
    age = 18
    color = 'yellow'

    #方法
    def eat(self):
        print('吃饭')

    def drink(self):
        print('喝水')

    #魔术方法__len__
    def __len__(self):
        print('len方法被触发')
        #去掉所有带下划线开头和结尾的成员
        #获取所有带下划线的成员
        result = {k:v for k,v in Human.__dict__.items() if k.startswith('__') and k.endswith('__')}
        print(result)
        #获取所有成员
        alls = Human.__dict__
        #获取用户定义的普通成员个数 相减
        return len(alls   ) - len(result)

#实例化对象
mmf = Human()
print(mmf)

result = len(mmf)
print(result)


#str魔术方法
'''
触发时机:使用print打印对象的时候或者str(对象)都可以触发
功能:定义对象转换为字符串的结果
参数:一个self接受对象
返回值:必须返回字符串类型
'''
class Human:
    #属性
    sex = 'man'
    age = 18
    name = 'wangcheng'

    #方法
    def la(self):
        print('lalala')

    def sa(self):
        print('谁先来')

    #魔术方法__str__
    def __str__(self):
        print('str被触发')
        return 'laxini'
        return self.name

#实例化对象
wc = Human()
#print(wc)

result = str(wc)
print(result)


#repr魔术方法
'''
触发时机:使用repr(对象)的时候触发
功能:定义repr函数的结果
参数:一个self接收当前对象
返回值:必须是字符串类型
'''
class Human:
    #属性
    sex = 'woman'
    age = 18
    height = '178cm'

    #方法
    def think(self):
        print('思想')

    def dream(self):
        print('I have a dream')

    #__repr__魔术方法
    def __repr__(self):
        print('repr方法被触发')
        return 'zw对象'
    #设定__str__和__repr__的魔术方法相同
    __str__ = __repr__
#实例化对象
zw = Human()
result = repr(zw)
print(result)

#测试repr函数
var = '123'
print(var)
result = repr(var)
print(result)


#__bool__魔术方法
'''
触发时机:使用bool(对象)的时候自动触发
功能:根据某个规则确定对象的布尔值转换结果
参数:一个self接受当前对象
返回值:必须是布尔类型
'''
class Human:
    #属性
    sex = 'woman'
    age = 20
    color = 'yellow'

    #方法
    def getMoney(self):
        print('赚钱')

    def spendMoney(self):
        print('花钱')

    #__bool__魔术方法
    def __bool__(self):
        #print('bool方法被触发')
        #设置当前对象 男 -> True 女 -> False
        if self.sex == 'man':
            return True
        return False
#实例化对象
bb = Human()
result = bool(bb)
print(result)


#format魔术方法

class Human:
    #属性
    name = 'feng'
    sex = 'man'
    age = 18
    #方法
    def lang(self):
        print('划船一身浪')

    def show(self):
        print('xiufeng')
    #__format__魔术方法
    def __format__(self,arg):
        print('format方法被触发')
        print(arg)

        #  >  <  ^
        #将arg(限定符号)进行拆分
        flag = arg[0] # @
        align = arg[1] # > < ^
        num = int(arg[2:]) # 6
        #判断对齐方式
        if align == '<':#左对齐
            result = self.name.ljust(num,flag)
        elif align == '>':#右对齐
            result = self.name.rjust(num,flag)
        elif align == '^':#居中对齐
            result = self.name.center(num,flag)
        return result

#实例化对象
sf = Human()
str = '{:#^10}去洗澡'
result = str.format(sf)
print(result)
#描述符相关的魔术方法

#描述符类
class Decription:

    #成员属性  共享值的操作
    def __init__(self):
        self.var = 'zhengyang'
    #定义三个操作
    #获取成员属性
    def __get__(self,obj,cls):#self描述符对象  obj接受描述的成员属性username的对象e  cls描述成员属性username所在的类Email
        #print(obj,cls)
        #隐藏名字中间的一个字符
        result = self.var[0]+'*'+self.var[-1]
        return result

    #设置成员属性
    def __set__(self,obj,value):#self描述符对象  obj接受描述的成员属性username的对象e  value设置的值
        #设置时候,默认添加思密达
        self.var = value + '思密达'

    #删除成员属性
    def __delete__(self,obj):#self描述符对象  obj接受描述的成员属性username的对象e
        #删除self.var就可以删除username的访问操作
        #根据密码是否为空决定是否可以删除用户名
        if obj.password == '':
            del self.var
        else:
            pass

class Email:
    #属性
    #希望对用户名进行管控(不是权限管控,而是内容管控)
    username = Decription()#交接操作 将username的操作管控交给描述符类的一个对象
    password = '123456'
    #方法
    def login(self):
        print('登录')
    def logout(self):
        print('注销')

#实例化对象
e = Email()

#获取成员属性
print(e.username)

#设置成员属性
e.username = '张望'
print(e.username)

#删除成员属性
del e.username
print(e.username)


#描述符2
class Email:
    #属性
    #username = ''
    password = ''
    #方法
    def __init__(self):
        #设置var对象成员为描述符的三个方法工作
        self.var = 'yang'

    def login(self):
        print('登录')

    def logout(self):
        print('注销')

    #获取属性的操作
    def getusername(self):
        result = self.var[0] + '*' +self.var[-1]
        return result

    #设置属性的操作
    def setusername(self,value):
        self.var = value

    #删除属性的操作
    def delusername(self):
        #删除的时候对self.var进行操作
        del self.var

    #将username属性交给property指定的函数管理
    username = property(getusername,setusername,delusername)

#实例化对象
e = Email()

#获取成员属性
print(e.username)

#设置成员属性
e.username = 'yangjun'
print(e.username)

#删除成员属性
#del e.username
#print(e.username)


#描述符3
class Email:
    #属性
    #username = ''
    password = ''
    #方法
    def __init__(self):
        #为描述符添加的用于数据通讯的成员属性
        self.var = '匿名'

    def login(self):
        print('登录')
    def logout(self):
        print('注销')

    #获取操作
    @property
    def username(self):
        result = self.var[0] + '*' + self.var[-1]
        return result
    #设置操作
    @username.setter
    def username(self,value):
        self.var = value
    #删除操作
    @username.deleter
    def username(self):
        del self.var

#实例化对象
e = Email()

#获取用户名
print(e.username)

#修改用户名
e.username = 'sun'
print(e.username)

#删除用户名
#del e.username
#print(e.username)
#与属性相关的魔术方法

class Man:
    #属性
    sex = 'man'
    age = 18
    color ='yellow'
    name = 'shizhipeng'

    #方法
    def __init__(self):
        self.gf = 'cortana'
        self.hobby = 'watchTV'

    def chou(self):
        print('piapia')
    def keng(self):
        print('坑娃的')
    '''
    #__getattr__()
   
    触发时机:访问一个不存在的成员属性的时候触发
    功能:1.防止访问不存在成员报错 2.可以为不存在的成员设置默认值
    参数:一个self接受对象  一个参数接受要访问的不存在的成员名
    返回值:可以有可以没有,如果有则是设置了访问的成员的值
    
    def __getattr__(self,attrname):
        #print(attrname)
        if attrname == 'height':
            return '175cm'
        elif attrname =='weight':
            return '75kg'
        else:
            return '对不起,不存在该属性'
    '''
    '''
    #__getattribute__()
    
    触发时机:访问对象成员时触发(无论是否存在)
    功能:可以限制过滤指定成员的值的访问
    参数:一个self接受当前对象  一个接受要访问的成员名
    返回值:可以有,可以没有  推荐根据程序设定(一般有!)
    
    def __getattribute__(self,attrname):

        if attrname == 'name':
            #不能通过当前对象访问成员(访问时绝对不允许使用[对象,成员名]的格式获取)触发递归!
            return object.__getattribute__(self,attrname)
        elif attrname == 'sex':
            return object.__getattribute__(self,attrname)
        else:
            return'对不起,成员不存在或者不允许访问'
    '''

    #__setattr__
    '''
    触发时机:对成员属性进行设置的时候触发
    功能:限制或者过滤对象成员的修改
    参数:一个self接受当前对象  一个接受修改的成员名  一个要修改的成员值
    返回值:没有返回值!
    '''
    def __setattr__(self,attrname,value):
        #可以在设置成员属性时候进行判断
        if attrname == 'sex' or attrname == 'name':
            pass
        else:
            object.__setattr__(self,attrname,value)

    #__delattr__ 魔术方法
    def __delattr__(self,attrname):
        #根据删除的内容决定是否允许删除
        if attrname == 'hobby':
            pass
        else:
            object.__delattr__(self,attrname)

#实例化对象
szp = Man()

'''
#获取对象的成员属性(getattr魔术方法)
print(szp.height)
print(szp.weight)
print(szp.length)
'''

#获取对象的成员属性(getattribute)
#print(szp.color)

#设置成员属性
#szp.sex = 'no man no woman'
#print(szp.sex)

#szp.name = '失了志'
#print(szp.name)

#szp.color = 'black'
#print(szp.color)

#删除成员属性
print(szp.__dict__)
del szp.gf
print(szp.__dict__)


#dir魔术方法
class Human:

    #属性
    sex = 'man'
    age = 18
    name = 'dog'

    #方法
    def eat(self):
        print('吃饭')
    def drink(self):
        print('喝水')

    #__dir__
    def __dir__(self):
        #获取所有可以访问的成员
        lists = object.__dir__(self)
        #过滤魔术方法  只留下自定义成员
        newlists = []
        for i in lists:
            if i.startswith('__') and i.endswith('__'):
                pass
            else:
                newlists.append(i)

        return newlists
#实例化对象
qw = Human()

#获取当前对象中所有存在的成员
result = dir(qw)
print(result)


#其他魔术方法

#自定义我们自己的整型类
class Myint(int):
    '''
    #__add__加法的魔术方法(int类中本来就有)
    def __add__(self,other):
        #print('add方法被触发')
        #print(self,other)
        return int(self) - int(other)
    '''
    #__radd__反向加法的魔术方法(int类中本来就有)
    def __radd__(self, other):
        #print('radd方法被触发')
        return int(self) * int(other)

#实例化对象
no1 = Myint(50)
#result = no1 + 15
#print(result)

'''
#练习:自定义一个整型,相加时进行的运算为10位数相乘+个位数相减
class Myint(int):
    def __add__(self,other):
        return int((self // 10) * (other // 10)) + int(self % 10 - other % 10)

no1 = Myint(18)

result = no1 + 25
print(result)
'''
#反向加法运算__radd__
result = no1 + 40
print(result)
'''
#练习:自定义一个整型,反向相加运算时获取2个数值的个位数的乘积作为结果
class Myint(int):
    def __radd__(self, other):
        return int(self % 10) * int(other % 10)

no1 = Myint(18)
result = 25 + no1
print(result)
'''


#比较运算
class Myint(int):

    #__eq__ 相等魔术方法
    def __eq__(self,other):
        #print('eq方法被触发')
        #print(self,other)
        #自定义规则:如果2个数都能被6整除 相等 其余都不相等
        if self % 6 == 0 and other % 6 == 0:
            return True
        else:
            return False

    #__gt__ 大于比较魔术方法
    def __gt__(self,other):
        if self % 5 > other % 5:
            return True
        else:
            return False
#实例化对象
no1 = Myint(34)
no2 = Myint(63)

#相等运算
result = no1 == no2
print(result)
'''
#练习:只要个位数相等 就相等 其余都不相等
class Myint(int):
    def __eq__(self,other):
        if (self % 10) == (other % 10):
            return True
        else:
            return False
no1 = Myint(12)
no2 = Myint(22)

result = no1 == no2
print(result)
'''
#大于比较运算
result = no1 > no2
print(result)

 

posted @ 2017-12-11 13:26  Sun阳  阅读(593)  评论(1编辑  收藏  举报