面向对象编程2(__new__( ),__getitem__( ),__call__( ),__doc__,__slots__,生成器与迭代器)

本文详细介绍了面向对象编程中的特殊方法,包括`__new__`、`__getitem__`、`__setitem__`、`__delitem__`、`__call__`、`__doc__`、`__slots__`以及`len()`。此外,还讨论了生成器和迭代器的使用,如何通过`next()`和`for`循环遍历生成器的元素。
摘要由CSDN通过智能技术生成

new( )

1.调用特殊方法__new__()创建实例对象
2.调用特殊方法__init__()对创建的实例对象进行初始化

class Parent(object):
    @classmethod
    def __new__(cls, *args, **kwargs):#cls接收的是子类Child
        print("父类的__new__()被调用,其形参cls对应实参的id:",id(cls))
        obj = super().__new__(cls)
        print("创建的实例对象的id:",id(obj))
        return obj
class Child(Parent):
    def __init__(self, name):
        print("子类的__new__()被调用,其形self对应实参的id:",id(self))
        self.name = name
child = Child("Mike")
>
>


父类的__new__()被调用,其形参cls对应实参的id: 2505126419896
创建的实例对象的id: 2505132259200
子类的__new__()被调用,其形self对应实参的id: 2505132259200

getitem(),setitem(),delitem()

想像字典或列表一样用中括号来操作数据,必须实现:
1.getitem(self,key)当执行操作obj[key]时,会自动调用该特殊方法
2.setitem(self,key,value)当执行操作obj[key]=value时,会自动调用该特殊方法
3.delitem(self,key)当执行操作del obj[key]时,会自动调用该特殊方法

class MyDict(object):
    def __init__(self):
        self.data = {}
        
    def __getitem__(self,key):
        return self.data[key]
    
    def __setitem__(self,key,value):
        self.data[key] = value
        
    def __delitem__(self,key):
        del self.data[key]
        
md = MyDict()
md["one"] = 18
md["two"] = 32
print(md.data)
>
>


{'one': 18, 'two': 32}

     
        

call(),callable()

call():如果在类对象中实现了特殊方法__call__()那么久可以像调用函数一样直接调用这个类对象的实例对象,从而会自动调用特殊方法__call__()
callable():用于判断对象是否可调用,除了函数对象可以调用之外,对于实现了特殊方法__call__()的类对象,其实例对象也是可调用的

class MyClass(object):
    def __call__(self, *args, **kwargs):
        print(args, kwargs)
        
mc = MyClass()
mc()
mc(1, 2,5, x = 3, y = 4,d = 6)
>
>


() {}
(1, 2, 5) {'x': 3, 'y': 4, 'd': 6}
callable(print)#内置函数是可调用的
>
>


True
def my_fun():#自定义函数也是可调用的
    pass
print(callable(my_fun))
>
>


True
print(callable(MyClass()))#实现了__call__的类对象的实例对象也是可以调用的
>
>


True

doc ,dict

doc:调用内置函数dir得到的类对象的所有属性中,有一个特殊的属性叫__doc__,用于表示类对象的文档字符串。
1.类对象文档字符串:位于类对象的第一行的字符串被称为类对象的文档字符串,通常用三个引号表示,类对象的文档字符串是对类对象的功能的简要概述
2.通过类对象的特殊属性__doc__可以访问类对象的文档字符串

在这里插入图片描述对于指定的类对象或实例对象,可以访问特殊属性__dict__获得该类对象或实例对象所绑定的所有属性和方法的字典
在这里插入图片描述

slots

在对应的类对象定义__slots__并给__slots__赋值一个所有元素都为字符串的列表或元组,对实例对象动态绑定的属性和方法的名称就只能来自于__slots__中的元素

class MyClass(object):
    __slots__ = ("attr1","do_sth1")
    mc = MyClass()
    mc.attr1 = 18
    print(mc.attr1)
>
>


18
def do_sth1(self):
    print("do_sth1被调用了")
    
from types import MethodType
mc.do_sth1 = MethodType(do_sth1, mc)
mc.do_sth1()
>
>


do_sth1被调用了

默认情况下,访问实例对象的属性是通过访问该实例对象的特殊属性__dict__来实现的,例如:访问obj.x其实是访问obj.dict[‘x’]
在类对象中定义了__slots__()后,其实例对象就不会再创建特殊属性__dict__(),slots()可以提高属性的访问速度

print(MyClass().__dict__)
>
>
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-21-11a41545445d> in <module>
----> 1 print(MyClass().__dict__)

AttributeError: 'MyClass' object has no attribute '__dict__'

slots__只对其所在的类对象的实例对象起作用,对其所在类对象的子类的实例对象不起作用,如父有__slots,子没有,所以他子可以任意调用

len()

如果不用def len(self):那么print(len(MyClass()))就不能用

生成器和迭代器

[i*i for i in range(8)]#列表推导式
>
>


[0, 1, 4, 9, 16, 25, 36, 49]
(i*i for i in range(8))#生成器表达式
>
>
<generator object <genexpr> at 0x00000247458C4840>

查看生成器对应的元素:
1.多次调用next(),每次调用都返回生成器的下一个元素,直到抛出错误
2.使用for循环对生成器进行迭代,这样就不会报错了

a = (i*i for i in range(8))
for j in a:
    print(j)
>
>


0
1
4
9
16
25
36
49
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值