Python面向对象编程(4)

    xiaoxiao2022-07-13  167

    首先介绍四个内置函数:issubclass() 、isinstance()、type()、dir(),其次介绍属性的增删改查,算术运算符重载,最后是类对象的特殊方法__str__()与__repr__()

    issubclass()

    用于判断类对象与类对象之间的关系 它接收两个实参,第一个实参是类对象,第二个实参是类对象或由类对象组成的元组。

    #当第二个实参是类对象时,如果第一个实参是第二个实参的子类,那么返回True #当第二个实参是类对象组成的元组时,如果第一个实参是第二个实参中任意一个类对象的子类,返回True class A(object): pass class B(object): pass class C(object): pass class D(A): pass print(issubclass(D,A)) #True print(issubclass(D,B)) #False print(issubclass(D,(A,B,C))) #True print(issubclass(bool,str)) #False print(issubclass(bool,int)) #True print(issubclass(bool,(str,int,dict))) #True print(issubclass(bool,(str,list,dict))) #False

    isinstance()

    接收两个实参,第一个实参是实例对象,第二个实参是类对象或由类对象组成的元组

    #当第二个实参是类对象时,如果第一个实参是第二个实参的实例对象,或者第一个实参是第二个实参的子类的实例对象,那么返回True #当第二个实参是类对象组成的元组时,如果第一个实参是第二个实参中任意一个类对象或其子类的实例对象,则返回True print(isinstance(D(),D)) #True print(isinstance(D(),A)) #True print(isinstance(D(),(D,B,C))) #True print(isinstance(D(),(A,B,C))) #True

    type()

    用于获得指定对象的类型 实例对象的类型是其对应的类对象,类对象的类型是type,也就是说,类对象是type的一个实例对象。

    class MyClass(object): pass mc = MyClass() print(type(mc)) #<class '__main__.MyClass'> print(type(MyClass)) #<class 'type'> def do_sth(): pass print(type(do_sth)) #<class 'function'> print(type(dir)) #<class 'builtin_function_or_method'> print(type(dir())) #<class 'list'> #可以使用运算符==判断某个对象的类型是否是指定的类型 #对于基本数据类型,可以直接使用其对应的类名,如果不是基本数据类型,需要使用标准库中的模块types中定义的变量 print(type(18) == int) #True print(type('abc') == str) #True print(type(do_sth) == function) NameError: name 'function' is not defined import types print(type(do_sth) == types.FunctionType) #True print(type(print) == types.BuiltinFunctionType) #True

    dir()

    对于制定的类对象或实例对象,可以调用内置函数dir()获得其所有可以访问的属性和方法(包括从父类中继承的属性和方法)的列表类对象与实例对象的结果是有区别的,类对象的结果中不包括实例属性 class MyClass(object): ca = "ca" def __init__(self): self.ia = "ia" def im(self): pass @classmethod def cm(cls): pass @staticmethod def sm(): pass print(dir(MyClass)) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'ca', 'cm', 'im', 'sm'] print(dir(MyClass())) ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'ca', 'cm', 'ia', 'im', 'sm']

    以双下划线__开头和结尾的属性被称为特殊属性,以双下划线__开头和结尾的方法被称为特殊方法,他们都是系统预定义的,我们自定义的属性名和方法名不要以双下划线__开头和结尾。

    属性的增删改查

    hasattr(object, name) 用于判断指定的对象object是否有参数name指定的属性或方法getattr(object, name[ , default]) 用于获取指定对象object中名为name的属性或方法 如果不指定参数default,那么当object中不存在名为name的属性或方法时,抛出AttributeError,如果指定参数default,同上情况,则返回default。setattr(object, name, value) 用于在指定对象object中添加或修改名为参数name的属性或方法,添加或修改后的值为value。等价于:object.name = valuedelattr(object, name) 用于删除指定对象object中名为参数name的属性或方法,等价于del object.name

    注意:只有在不知道对象信息的情况下才会去获取对象的信息,因此如果可以直接写:object.name,就不要写为getattr(object, ‘name’)。

    class MyClass(object): def __init__(self): self.x = 1 def do_sth(self): print("do_sth被调用了") mc = MyClass() print(hasattr(mc, 'x')) # True print(hasattr(mc, 'do_sth')) # True print(hasattr(mc, 'y')) # False print(getattr(mc, 'x')) # 1 print(getattr(mc, 'y')) # AttributeError: 'MyClass' object has no attribute 'y' print(getattr(mc, 'y', 2)) # 2 print(getattr(mc, 'y','查找的属性或方法不存在')) # 查找的属性或方法不存在 f = getattr(mc, 'do_sth') f() # do_sth被调用了 setattr(mc, 'z', 3) #等价于 mc.z = 3 print(getattr(mc,'z')) # 3 delattr(mc, 'z') print(hasattr(mc, 'z')) # False

    算术运算符重载

    标准算术运算符在默认情况下 不能用于自定义类对象的实例对象

    class MyClass1(object): pass class MyClass2(object): pass print(MyClass1() + MyClass2()) TypeError: unsupported operand type(s) for +: 'MyClass1' and 'MyClass2'

    如果想让标准算术运算符可以用于自定义类对象的实例对象,必须在自定义类对象中实现标准算术运算符对应的以特殊方法:

    ’ + '对应的特殊方法是__add__() 和 __radd __()’ - ’ __sub __() 和 __rsub __()’ * ’ __mul __() 和 __rmul __()’ / ’ __truediv __() 和 __rtruediv __()’ // ’ __floordiv __() 和 __rfoordiv __() class MyClass1(object): def __add__(self, other): return "这是__add__+的结果" class MyClass2(object): def __radd__(self, other): return "这是__radd__+的结果" obj1 = MyClass1() obj2 = MyClass2() print(obj1 + obj2) #这是__add__+的结果 ################################################################## class MyClass1(object): pass class MyClass2(object): def __radd__(self, other): return "这是__radd__+的结果" obj1 = MyClass1() obj2 = MyClass2() print(obj1 + obj2) #这是__radd__+的结果 ################################################################## class MyClass1(object): pass class MyClass2(object): pass obj1 = MyClass1() obj2 = MyClass2() print(obj1 + obj2) # TypeError: unsupported operand type(s) for +: 'MyClass1' and 'MyClass2' ################################################################### class MyClass1(object): def __add__(self, other): print( "特殊方法__add__被调用") return NotImplemented class MyClass2(object): def __radd__(self, other): return "这是__radd__+的结果" obj1 = MyClass1() obj2 = MyClass2() print(obj1 + obj2) 特殊方法__add__被调用 这是__radd__+的结果 ################################################################### class MyClass1(object): def __add__(self, other): print( "特殊方法__add__被调用") return NotImplemented class MyClass2(object): def __radd__(self, other): print( "特殊方法__radd__被调用") return NotImplemented obj1 = MyClass1() obj2 = MyClass2() print(obj1 + obj2) 特殊方法__add__被调用 特殊方法__radd__被调用 Traceback (most recent call last): File "<ipython-input-19-f617a8da3637>", line 16, in <module> print(obj1 + obj2) TypeError: unsupported operand type(s) for +: 'MyClass1' and 'MyClass2'

    __str __() 与 __repr __()

    用于自定义并返回实例对象的字符串表示形式

    class MyClass(object): pass mc = MyClass() mc # <__main__.MyClass at 0x1a18033b6a0> print(mc) #<__main__.MyClass object at 0x000001A18033B6A0> str(mc) #'<__main__.MyClass object at 0x000001A18033B6A0>' repr(mc) #'<__main__.MyClass object at 0x000001A18033B6A0>' ########################################################## class MyClass(object): def __str__(self): return "__str__被调用" mc = MyClass() mc #<__main__.MyClass at 0x1a18033b160> print(mc) #__str__被调用 str(mc) #'__str__被调用' repr(mc) # '<__main__.MyClass object at 0x000001A18033B160>' ########################################################## class MyClass(object): def __repr__(self): return "__repr__被调用" mc = MyClass() mc #__repr__被调用 print(mc) #__repr__被调用 str(mc) #'__repr__被调用' repr(mc) #'__repr__被调用' ########################################################## class MyClass(object): def __str__(self): return "__str__被调用" def __repr__(self): return "__repr__被调用" mc = MyClass() mc #__repr__被调用 print(mc) #__str__被调用 str(mc) #'__str__被调用' repr(mc) #'__repr__被调用' 1、当在交互式命令行中直接打印一个实例对象时,如果在实例对象对应的类对象中实现了特殊方法__repr__(),会自动调用该方法;否则会打印实例对象对应的类对象和实例对象在内存中的地址。2、当调用内置函数 print 打印一个实例对象时,如果在实例对象对应的类对象中实现了特殊方法__str__(),会调用该方法;否则如果实现了__repr__(),会调用该方法;否则,会打印实例对象对应的类对象和实例对象在内存中的地址。3、当调用内置函数 str 创建字符串并且实参是一个实例对象时,如果在实例对象对应的类对象中实现了特殊方法__str__(),在内置函数 str 的内部会自动调用该方法;否则如果实现了__repr__(),会调用该方法,否则会打印实例对象对应的类对象和实例对象在内存中的地址。4、当调用内置函数 repr 创建字符串并且实参是一个实例对象时,如果在实例对象对应的类对象中实现了特殊方法__repr__(),在内置函数 repr 的内部会自动调用该方法;否则会打印实例对象对应的类对象和实例对象在内存中的地址。

    内置函数str() 和repr()都是返回对象的字符串表示,其区别在于: str()的返回值是给用户看的,更加用户友好。 repr()的返回值是给程序开发者看的,是为调试服务的。

    最新回复(0)