2021-4-4python语法知识(11)面向对象高级

1:复习

class Person:
    def __init__(self,local,name):  #local,name属性名

        self.local=local
        self.name=name
    def play(self):					#类的方法
        print(f'{self.name}的爱好')
na=Person('china','nana')

为什么要内置函数:
有些时候没有那些属性程序就会报错
对程序不太友好
2:判断实例对象是否存在:
hasattr()实例化对象,属性。

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
    def play(self):
        print(f'{self.name}的爱好')
na=Person('china','nana')
print(hasattr(na,'local'))
print(hasattr(na,'name'))
print(hasattr(na,'color'))

输出结果:

True
True
False

3:
getattr()实例对象,属性
输出对象属性
相当于实例对象点属性

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
    def play(self):
        print(f'{self.name}的爱好')
na=Person('china','nana')

print(na.local)
print(getattr(na,'local'))

输出结果:

china
china

4:
setattr()实例对象,属性,属性内容

增加属性或者修改属性
原本有那个属性就改,没有就增加

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
    def play(self):
        print(f'{self.name}的爱好')
na=Person('china','nana')

setattr(na,'age',18)
setattr(na,'name','haha')
print(na.age)
print(na.name)

5:
delattr()实例对象,属性
删除属性

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
    def play(self):
        print(f'{self.name}的爱好')
na=Person('china','nana')

delattr(na,'name')
print(hasattr(na.name))

直接报错,因为不存在

与三目运算的结合:

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
    def play(self):
        print(f'{self.name}的爱好')
na=Person('china','nana')
a=getattr(na,'age') if hasattr(na,'age') else setattr(na,'age',18)
print(a)

6:
issubclass()类,类
判断是否为子类:
判断后者是不是前者的子类:

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
    def play(self):
        print(f'{self.name}的爱好')
na=Person('china','nana')

class People(Person):
    pass

print(issubclass(People,Person))

:

True

7:
isinstance()实例对象,类名
判断实例对象是否为类的实例

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
    def play(self):
        print(f'{self.name}的爱好')
na=Person('china','nana')

class People(Person):
    pass

print(isinstance(na,Person))
print(isinstance(na,People))
print(isinstance(na,(People,Person)))
True
False
True

8:在这里插入图片描述
属性调用过程如果存在就可以打印出结果(添加print),
如果属性不存在就会报错,
只要我们修改报错那个部分,就可以实现不报错。
如下:

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name
        
    def play(self):
        print(f'{self.name}的爱好')
        
    def __getattribute__(self,item):#两个参数
        print(item)#item就是自己输入的那个不存在的属性名
        print('no attribute')
    
na=Person('china','nana')
print(na.age)

如果不修改就会报错了

9:魔术方法__new__
创建实例对象

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name

     #这个函数优先调用,
    #表示重写,因此上面的init函数的实例化对象全都无效
    def __new__(cls,*args,**kwargs):
        print('这是new')
na=Person('china','nana')
print(getattu(na,'name'))

输出完

这是new

就会报错

将new方法继承父类
就可以使用了

class Person:
    def __init__(self,local,name):

        self.local=local
        self.name=name

    #这个函数优先调用
    #表示重写,因此上面的init函数的实例化对象全都无效
    def __new__(cls,*args,**kwargs):#cls就是这个类本身
        print('这是new')
        return super().__new__(cls)   #返回变量
na=Person('china','nana')
print(na.name)

10:单例模式

class Person:
    def __init__(self,local):
        self.local=local

    def __new__(cls,*args,**kwargs):
        return super().__new__(cls)
        
na=Person('china')
oo=Person('china')

我们发现na,oo的属性名是一样的
如何只能让一个存在(地址)呢?

对new方法进行修改
如下:

class Person:
    def __init__(self,local):
        self.local=local


    def __new__(cls,*args,**kwargs):
#*args,**kwargs分别是列表不定长,元组不定长
        if not hasattr(cls,'_istance'):#istance是习惯用法,就是一个变量
        #这里判断是否存在,不存在就把实例对象赋值给_istance
            cls._istance=super().__new__(cls)
        return cls._istance
        #_instance肯定是不存在的所以自动执行下一行把实例对象赋值给
        #cls_istance,同时他就存在了,然后返回。
        #因此na,oo的地址就一致了
    
na=Person('china')
oo=Person('哈哈')

11:输出魔法方法:

class Person:
    def __init__(self,local):
        self.local=local

    def __new__(cls,*args,**kwargs):

        if not hasattr(cls,'_istance'):
            cls._istance=super().__new__(cls)
        return cls._istance
oo=Person('哈哈')
print(oo)

看不懂!!

<__main__.Person object at 0x00000168053F67F0>

为了让我们读懂:
就有了输出方法:如下
方法一:str
在交互模式也要输入print

class Person:
    def __init__(self,local):
        self.local=local

    def __new__(cls,*args,**kwargs):

        if not hasattr(cls,'_istance'):
            cls._istance=super().__new__(cls)
        return cls._istance

    def __str__(self):
        return 'this is __str__%s' %self.local

oo=Person('哈哈')
print(oo)

这样子咱们就能读懂了

this is __str__哈哈

方法二:repr
在交互模式下不用输入print,可以直接打印

class Person:
    def __init__(self,local):
        self.local=local


    def __new__(cls,*args,**kwargs):

        if not hasattr(cls,'_istance'):
            cls._istance=super().__new__(cls)
        return cls._istance

    #def __str__(self):
      #  return 'this is __str__%s' %self.local

    def __repr__(self):
        return 'this is __repr__%s' %self.local

oo=Person('哈哈')
print(oo)

两种方法如果同时都有:默认先调用str方法

12:call
把实例对象变为可调用的方法

class Person:
    def __init__(self,local):
        self.local=local


    def __new__(cls,*args,**kwargs):

        if not hasattr(cls,'_istance'):
            cls._istance=super().__new__(cls)
        return cls._istance

    #def __str__(self):
      #  return 'this is __str__%s' %self.local

    def __repr__(self):
        return 'this is __repr__%s' %self.local

    def __call__(self):
        print('用实例对象做方法')

oo=Person('哈哈')
print(oo)
oo()
this is __repr__哈哈
用实例对象做方法

协议:两个或者两个以上的魔术方法才能实现的效果
13:序列协议:下标取值

class Person:
    def __init__(self,*args):#元组不定长,之后就不用一个往里输了
        self.values=[x for x in args]#保存元组里单位值
        self.index=list(enumerate(self.values))#通过枚举获得索引
        #打印出来的就是下标,值

    def __getitem__(self,key):
        return self.index[key]
lee=Person(2,5,6)
print(lee[2])

14:迭代协议:iter,next

#类想要迭代必须添加迭代协议 
class Number():
    def __init__(self,end=10):
        self.start=0
        self.end=end#迭代十次
    def __iter__(self):#让类变成可迭代对象
        return self
    def __next__(self):#迭代器f=li.__iter__()
        self.start += 1
        if self.start>=self.end:
            #主动报错 raise抛出异常
            raise StopIteration
        return self.start
nu=Number()
#调用next(nu)就可以迭代了

15:上下文协议:

import time
#让类有上下文协议,就可以使用with调用类
class Rutime:
    def __enter__(self):
        self.start=time.time()
        return self.start
    def __exit__(self,exc_type,exc_val,exc_tb):#异常的类型异常的值异常的信息
        self.end=time.time()
        self.run=self.end-self.start#运行时间
        print('时间运行:%s'%self.run)

with Rutime():
    for i in range(1000000):
        pass
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值