13周学习笔记

    xiaoxiao2023-11-09  223

    isubclass()与isinstance()

    ###内重函数issubcLass()用于判断类对象与类对象之间的关系。

    ###内函数isinstance()用于判断实例对象与类对象之间的关系。

    ###内置园数issubcLass接收两个实参,第一个实参是类对象,第二个实参是类对象现由类对象组成的元组。

    ###当第二个实参是类对象时, 如果第一个实参是第二个实参的子类,那么返回True.

    ###当第二个实参是类对象组成的元组时,如果第一个实参是第二个实参中任意一个类对象的子类, 返回True。

    class A(object): pass ​ class B(object): pass ​ class C(object): pass ​ class D(A): pass

    print(issubclass(D, A)) print(issubclass(D,B)) print(issubclass(D, (B, A, C))) print(issubclass(D, (B, C))) print(issubclass(bool, int)) print(issubclass(bool,str)) print(issubclass(bool,(str,int,dict))) print(issubclass(bool,(str,list,dict))) True True True True True False True False

    ​ 内置函数type()用于获得指定对象的类型。

    实例对象的类型就是它对应的类的对象,类对象的类型是type,也就是说,类对象是type的一个实例对象。

    class MyClass(object): pass ​ mc = MyClass() print(type(mc)) <class ‘main.MyClass’>

    print(type(18)) print(type(‘abc’)) print(type(MyClass)) <class ‘int’> <class ‘str’> <class ‘type’>

    print(type(int)) print(type(str)) <class ‘type’> <class ‘type’>

    ​ ###自定义函数对象的类型是function

    ###内置函数对象的类型是builtin_function_or_method

    def do_sth(): pass print(type(do_sth)) <class ‘function’>

    print(type(dir)) <class ‘builtin_function_or_method’>

    ​ ###可以使用运算符==判断某个对象的类型是否是指定的类型。

    ###对于基本数据类型,可以直接使用其对用的类名;如果不是基本数据类型,需要使用标准库中的模块types中定义的变量。

    print(type(dir())) <class ‘list’>

    print(type(18) == int) print(type(‘abc’) == str) True True

    print(type(do_sth) == function)

    NameError Traceback (most recent call last) in () ----> 1 print(type(do_sth) == function)

    NameError: name ‘function’ is not defined

    print(type(print) == builtin_function_or_method)

    NameError Traceback (most recent call last) in () ----> 1 print(type(print) == builtin_function_or_method)

    NameError: name ‘builtin_function_or_method’ is not defined

    import types print(type(do_sth) == types.FunctionType) print(type(print) == types.BuiltinFunctionType) True True dir()

    class MyClass(object): ca = “ca”

    def __int__(self): seif.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’, ‘int’, ‘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’, ‘int’, ‘le’, ‘lt’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘ca’, ‘cm’, ‘im’, ‘sm’] ###对于制定的类对象或实例对象,可以调用内置函数dir()获得其所有可以访问的属性和方法(包括从父类中继承的属性和方法)的列表。

    ###类对象与实例对象的结果是有区别的,类对象的结果中不包括实例属性。

    ###调用内置函数dir()后的返回值中,很多属性和方法都是以双下划线开头和结尾的, 这些性和方法中的绝大多数都继承自类object.

    ###以双下划线开头和结尾的 性被称为特殊属性,以双下划线开头和结尾的方法被称为特殊方法。

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

    ###在我们自定义类对象时, 经常会重写一个或多个特殊方法,例如init。 特殊方法会在特定的情形F被自动调用,很少需要手动调用特殊方法。

    print(dir(object)) [‘class’, ‘delattr’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘gt’, ‘hash’, ‘init’, ‘init_subclass’, ‘le’, ‘lt’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’] ###1. hasattr(object, name )

    ###用于判断指定的对象object是否有参数name指定的属性或方法。

    ###2. getattr(object, name[, default])

    ###用于获取指定的对象object中名为name的属性或方法。

    ###如果不指定参数default,那么当object中不存在名为name的属性或方法时,抛出AttributeError。

    ###如果指定了参数default,那么当object中不存在名为name的性或方法时,就会返回default。

    ###getattr(object, name)等价于: object.name。

    ###3. setattr(object, name, value)

    ###用于在指定的对象object中添加或修改名为参数name的属性或方法,添加或修改后的值为value。

    ###setattr(object, name, value)等价于: object.name = value。

    ###4. delattr(object, name)

    ###用于删除指定的对象bject中名为参数name的属性或方法。

    ###delattr(object, name)等价于 del object ,name。

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

    class MyClass(object): def int(self): self.x = 1

    def do_sth(self): print("do_sth被调用")

    ​ mc = MyClass() ​ print(hasattr(mc,‘x’)) print(hasattr(mc,‘do_sth’)) print(hasattr(mc,‘y’)) False True False

    print(getattr(mc,‘x’))

    AttributeError Traceback (most recent call last) in () ----> 1 print(getattr(mc,‘x’))

    AttributeError: ‘MyClass’ object has no attribute ‘x’

    print(getattr(mc,‘y’))

    AttributeError Traceback (most recent call last) in () ----> 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被调用 标准算术运算符在默认情况下不能用于自定义类对象的实例对象。

    class MyClass1(object): pass ​ class MyClass2(object): pass ​ print(MyClass1()+MyClass2())

    TypeError Traceback (most recent call last) in () 5 pass 6 ----> 7 print(MyClass1()+MyClass2())

    TypeError: unsupported operand type(s) for +: ‘MyClass1’ and ‘MyClass2’

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

    +对应的特殊方法是add()和radd (); 2.一对应的特殊方法是sub()和 rsub (); *对应的特殊方法是 mul ()和rmul() ; /对应的特殊方法是truediv()和 rtruediv__(); //对应的特殊方法是floordv()和 rfloordiv()。

    print(dir(list)) [‘add’, ‘class’, ‘contains’, ‘delattr’, ‘delitem’, ‘dir’, ‘doc’, ‘eq’, ‘format’, ‘ge’, ‘getattribute’, ‘getitem’, ‘gt’, ‘hash’, ‘iadd’, ‘imul’, ‘init’, ‘init_subclass’, ‘iter’, ‘le’, ‘len’, ‘lt’, ‘mul’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘reversed’, ‘rmul’, ‘setattr’, ‘setitem’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘append’, ‘clear’, ‘copy’, ‘count’, ‘extend’, ‘index’, ‘insert’, ‘pop’, ‘remove’, ‘reverse’, ‘sort’] 假设两个运算数obj1和obj2,以+为例,对于obj1 + obj2, 需要在obj1对应的自定义类对象中实现特殊方法add (), 或在obj2对应的自定义类对象中实现特殊方法radd () (radd中的r是right的缩写 ,因为obj2位于运算符+的右边,所以实现的特殊方法是radd(); 因为obj1位于运算符+的左边,所以实现的特殊方法是add())。

    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): 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__被调用

    TypeError Traceback (most recent call last) in () 12 obj2 = MyClass2() 13 —> 14 print(obj1+obj2)

    TypeError: unsupported operand type(s) for +: ‘MyClass1’ and ‘MyClass2’

    str()与repr()

    类对象的特殊方法之str()与repr()用于自定义并返回实例对象的字符串表示形式。

    #第一系列 class MyClass(object): pass ​ mc = MyClass() mc <main.MyClass at 0x1e659982278>

    print(mc) <main.MyClass object at 0x000001E659982278>

    str(mc) ‘<main.MyClass object at 0x000001E659982278>’

    repr(mc) ‘<main.MyClass object at 0x000001E659982278>’

    #第二系列 class MyClass(object): def str(self): return “__str__被调用” ​ mc = MyClass() mc <main.MyClass at 0x1e6598e0f28>

    print(mc) str(mc) repr(mc) __str__被调用 ‘__str__被调用’ ‘<main.MyClass object at 0x000001E6598E0F28>’ ###类对象的特殊方法之str()和repr()用于自定义并返回实例对象的字符串表示形式。

    ###1.当在交互式命令行中直接打印一个实例对象时,

    ###如果在实例对象对应的类对象中实现了特殊方法repr(), 会自动调用该方法;

    ###否则,会打印实例对象对应的类对象和实例对象在内存中的地址。

    ###2.当调用内置函数print打印一个实例对象时,

    ###如果在实例对象对应的类对象中实现了特殊方法str(), 会自动调用该方法;

    ###否则,如果在实例对象对应的类对象中实现了特殊方法repr(), 会自动调用该方法;

    ###否则,会打印实例对象对应的类对象和实例对象在内存中的地址。

    ###3.当调用内置数str创建字符串并且实参是一个实例对象时,

    ###如果在实例对象对应的类对象中实现了特殊方法str(),在内置数str的内部会自动调用该方法;

    ###否则,如果在实例对象对应的类对象中实现了特殊方法repr(), 在内置函数str的内部会自动调用该方法;

    ###否则,会打印实例对象对应的类对象和实例对象在内存中的地址。

    ###4.当调用内置函数repr创建字符串并且实参是一个实例对象时,

    ###如果在实例对象对应的类对象中实现了特殊方法repr(),在内置函数repr的内部会自动调用该方法;

    ###否则,会打印实例对象对应的类对象和实例对象在内存中的地址。

    通常情况下,类对象的特殊方法str()和repr()的实现代码是一样的,因此,当实现了其中一个后,可以把其方法名赋值给另一个的方法名。

    class MyClass(object): def str(self): return “这是实例对象的字符串表示形式”

    repr = str

    ###内置函数str()和repr()都返回对象的字符串表示,其区别在于:

    ###str()的返回值是给用户看的,更加用户友好;

    ###repr()的返回值是给程序开发者看的,是为调试服务的。

    str(“Hello,\nworld!”) ‘Hello,\nworld!’

    repr(“Hello,\nworld!”) “‘Hello,\nworld!’”

    最新回复(0)