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!’”