面向对象学习笔记5

类的多态性:某个函数依据参数的实例类型(通常是基类实例或者子类实例),可以实现不同的输出。

class F1:
    pass
    
class S1(F1):

    def show(self):
        print ('S1.show')
        
class S2(F1):

    def show(self):
        print ('S2.show')
        
# 由于在Java或C#中定义函数参数时,必须指定参数的类型,为了让Func函数既可以执行S1对象的show方法,
#又可以执行S2对象的show方法,所以,定义了一个S1和S2类的父类,而实际传入的参数是:S1对象和S2对象 
  
def Func(obj):
    """Func函数需要接收一个F1类型或者F1子类的类型"""
    obj.show()
    
s1_obj = S1()
Func(s1_obj) # 在Func函数中传入S1类的对象
#s1_obj,执行 S1 的show方法,结果:
#S1.show
s2_obj = S2()
Func(s2_obj) # 在Func函数中传入Ss类的对象
#ss_obj,执行 Ss 的show方法,结果:
#S2.show

在这里插入图片描述

类的内置方法及调用:

>>> class P:
...     def __del__(self):
...         print("bye!")
...
>>> p=P()
>>> del p
bye!
>>> class P:
...     """P class"""
...     pass
...
>>> p=P()
>>> p.__doc__
'P class'
>>> p.__module__
'__main__'
>>> p.__class__
<class '__main__.P'>
>>> class P:
...     def __repr__(self):
...         print("repr is invoked!")
...         return "repr method!"
...     def __str__(self):
...         print("str method is invoked!")
...         return "str method!"
...
>>> p=P()
>>> p
repr is invoked!
repr method!
>>> print(p)
str method is invoked!
str method!

>>> repr(p)
repr is invoked!
'repr method!'
>>> str(p)
str method is invoked!
'str method!'
>>> class P:
...     def __call__(self):
...         print("call me now!")
...
>>> p = P()
>>> p
<__main__.P object at 0x0077F690>
>>> p()
call me now!
>>> class P:
...     def __call__(self,value):
...         print(value)
...
>>> p=P()
>>> p(100)
100
>>> class P:
...     number=100
...     def __init__(self,value):
...         self.value = value
...     def print_sth(self):
...         pass
...
>>> p=P(1)
>>> p.__dict__
{'value': 1}
>>> P.__dict__
mappingproxy({'__module__': '__main__', 'number': 100, '__init__': <function P._
_init__ at 0x02170A08>, 'print_sth': <function P.print_sth at 0x021709C0>, '__di
ct__': <attribute '__dict__' of 'P' objects>, '__weakref__': <attribute '__weakr
ef__' of 'P' objects>, '__doc__': None})
>>>

类的特殊成员

getitemsetitemdelitem
用于索引操作,如字典。以上分别表示获取、设置、删除数据

# -*- coding:utf-8 -*-

class Foo(object):

    def __getitem__(self, key):
        print ('__getitem__',key)
        
    def __setitem__(self, key, value):
        print ('__setitem__',key,value)
        
    def __delitem__(self, key):
        print ('__delitem__',key)
        
obj = Foo()
result = obj['k1'] # 自动触发执行 __getitem__
obj['k2'] = 'wupeiqi' # 自动触发执行 __setitem__
del obj['k1'] # 自动触发执行 __delitem__

在这里插入图片描述

小练习:
实现类似字典的功能:obj[‘k1’]如果存在,读出来值,不存在返回None;obj[‘k2’]='wupeiqi’可以赋值成功并且通过obj[‘k2’]来读取值,删除obj[‘k2’]的时候,把k2的value和key都删除。
提示:类有个实例变量是个字典来实现上面的功能

# -*- coding:utf-8 -*-

class Foo(object):

    def __init__(self):
        self.d = {}

    def __getitem__(self, key):
        if key in self.d:
            return self.d[key]
        else:
            return None
        
    def __setitem__(self, key, value):
        self.d[key] = value
        
    def __delitem__(self, key):
        if key in self.d:
            del self.d[key]
        print("del %s" %key)
        
obj = Foo()
result = obj['k1'] # 自动触发执行 __getitem__
print(result)
obj['k2'] = 'wupeiqi' # 自动触发执行 __setitem__
print(obj['k2'])
del obj['k1'] # 自动触发执行 __delitem__

类的变量,方法,实例的小结

class P:
    number = 100
    def __init__(self):
        print(P.number) #通过类名调用类变量
        print(self.number) #通过实例调用类变量
        self.number = 30  #生成了新的实例变量,覆盖了类变量number
        print(self.number)#通过实例变量把类变量覆盖了
  
    @classmethod  #类方法,必须有cls的参数,不能包含实例变量
    def func(cls,value):
        print(P.number)
        print(value) #局部变量

    @staticmethod  #静态方法,不能包含实例变量
    def func1(value):
        print(P.number)
        print(value) #局部变量
    
    def print_str(self,content): #实例方法,可以包含实例变量和类变量
        print(content) #局部变量
        print(self.number)#访问实例变量
        print(P.number)#访问类变量

#类是模板P
#实例是通过模板生成的产品p
P.func(50)#调用类方法
p=P()#实例化
p.func(50)#调用类方法
p.print_str("gloryroad")#通过实例调用实例方法
#P.print_str("gloryroad")#通过类名调用实例方法,会出错
P.func1("gr") #通过类名调用静态方法
p.func1("gr") #通过实例调用静态方法

类的特殊成员__new__

new() 方法的特性:
new() 方法是在类准备将自身实例化时调用。
new() 方法始终都是类的静态方法,即使没有被加上静态方法装饰器。

# -*- coding:utf-8 -*-
class A(object):

    def __init__(self):#实例已经有了,对实例做一些初始化的动作
        print ("init")     
                
    def __new__(cls,*args, **kwargs):#真正的生成实例对象的方法,第一个参数必须是cls,传递的必须是一个类对象
        print ("new %s"%cls)
        return object.__new__(cls, *args, **kwargs)#必须返回object.__new__或者是cls的父类.__new__
        
A()

在这里插入图片描述
继承自object的新式类才有__new__。
__new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供。
__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以
return父类__new__出来的实例,或者直接是object的__new__出来的实例。
__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值。
若__new__没有正确返回 当前类 cls的实例,那__init__是不会被调用的,即使是父类的实例也不行。

单例----一个类对象只能生成一个实例

用__new__方法实现单例,并在将一个类的实例绑定到类变量_instance上,如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回;如果cls._instance不为None,直接返回cls._instance。
super(Singleton, cls)表示获取Singleton父类对象,super也是个类,返回一个super对象(即父类对象),cls是Myclass类对象。

class Singleton(object):

    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):#判断类对象里面有没有类变量_instance,这个类变量里面存的是该类的实例
            orig = super(Singleton, cls)#生成了Singleton的父类object
            print(type(orig))
            cls._instance = orig.__new__(cls,*args, **kw)#实例化该类
        return cls._instance
        
class MyClass(Singleton):
    a = 1
    
one = MyClass()
two = MyClass()
two.a = 3
print (one.a)
#3
#one和two完全相同,可以用id(), ==,is检测
print (id(one))
#29097904
print (id(two))
#29097904
print (one == two)
#True
print (one is two)
#True

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值