issubclass()
issubclass():判断类对象与类对象之间的关系
内置函数接受两个参数:
第一个实参是类对象
第二个实参是类对象或类对象组成的元组
当第二个实参是类对象时,如果第一个实参是第二个实参的子类,那么返回True。
当第二个实参是类对象组成的元组时,如果第一个实参是第二个实参中任意一个类对象的子类,返回True。
class A(object):
pass
class B(object):
pass
class C(object):
pass
class D(A):
pass
print(issubclass(D,A))#判断D是不是A的子类
print(issubclass(D,B))#判断D是不是B的子类
>>
True
False
print(issubclass(D,(B,A,C)))
print(issubclass(D,(B,C)))
>>
True
False
print(issubclass(bool,int))
print(issubclass(bool,str))
>>
True
False
print(issubclass(bool,(str,int,dict)))
print(issubclass(bool,(str,list,dict)))
>>
True
False
isinstance()
isinstance():判断实例对象与类对象之间的关系
第一个实参是实例对象
第二个实参是类对象或类对象组成的元组
当第二个实参是类对象时,如果第一个实参是第二个实参的实例对象,或者第一个实参是第二个实参的子类的实例对象,那么返回True。
当第二个实参是类对象组成的元组时,如果第一个实参是第二个实参中任意一个类对象或其子类的实例对象,那么返回True。
class A(object):
pass
class B(object):
pass
class C(object):
pass
class D(A):
pass
print(isinstance(D(),D))#判断D()是不是D的实例对象
print(isinstance(D(),A))
>>
True
True
print(isinstance(D(),(D,B,C)))
print(isinstance(D(),(B,A,C)))
>>
True
True
type()
获得指定对象的类型。
实例对象的类型就是它所对应的类对象。
类对象的类型是‘type’,也就是说,类对象是type的一个实例对象。
class MyClass(object):
pass
mc = MyClass()
print(type(mc))
>>
<class '__main__.MyClass'>
class MyClass(object):
pass
print(type(MyClass))
>>
<class 'type'>
print(type(18))
>>
<class 'int'>
print(type('abc'))
>>
<class 'str'>
print(type(int))
>>
<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'>
print(type(dir()))
>>
<class 'list'>
可以使用==判断某个对象的类型是否是指定的类型。
对于基本数据类型,可以直接使用其对应的类名;如果不是基本数据类型,需要使用标准库中的模块types中定义的变量。
print(type(18)== int)
>>
True
print(type('abc')==str)
>>
True
print(type(do_sth)==function)
>>
NameError
print(type(print)==builtin_function_or_method)
>>
NameError
import types
print(type(do_sth)==types.FunctionType)
print(type(print)==types.BuiltinFunctionType)
>>
True
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']
调用内置函数dir()后的返回值中,很多属性和方法都是以下划线__开头和结尾的,这些属性和方法中绝大多数都继承自类object。
以双下划线 __ 开头和结尾的属性称为特殊属性,以双下划线 __ 开头和结尾的方法称为特殊方法。
特殊属性和特殊方法都是系统预定义的,我们自定义的属性和方法名不要以__开头和结尾。
在我们自定义类对象时,经常会重写一个或多个特殊方法,例如 __ int __ 。特殊方法会在特定的情形下被自动调用,很少需要手动调用特殊方法。
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])
用于获取指定的对象obj ect中名为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)
用于删除指定的对象object中名为参数name的属性或方法。
delattr(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'))
print(hasattr(mc,'do_sth'))
print(hasattr(mc,'y'))
##结果显示
True
True
False
print(getattr(mc,'x'))
>>
1
print(getattr(mc,'y'))
>>
AttributeError: 'MyClass' object has no attribute 'y'
print(getattr(mc,'y',2))#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')#删除z属性
print(hasattr(mc,'z'))
>>
False
算术运算符重载
标准算术运算符在默认情况下不能用于自定义类对象的实例对象。
如果想要标准运算符可以用于自定义类对象的实例对象,必须在自定义类对象中实现标准运算符对应的以下特殊方法:
+对应的特殊方法是__add__()和__radd__();
-对应的特殊方法是__sub__()和__rsub__();
*对应的特殊方法是__mul__()和__rmul__();
/对应的特殊方法是__truediv__()和__rtruediv__();
//对应的特殊方法是__floordiv__()和__rfoordiv__().
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对应的自定义类对象中实现特殊方法__ and __ (),或在obj2对应的自定义类对象实现的特殊方法 __ radd __ ()(radd中的r是right的缩写,因为obj2位于运算符+的右边,所以实现的特殊方法是__ radd __ ();因为obj1位于运算符+的左边。所以实现的方法是__ dd __ ())。
类对象的特殊方法之 __ str __ 和 __ repr __ 用于自定义并返回实例对象的字符串表示形式。
class MyClass(object):
pass
mc = MyClass()
mc
>>
<__main__.MyClass at 0x25ee62d7438>
print(mc)
>>
<__main__.MyClass object at 0x0000025EE62D7438>
str(mc)
>>
'<__main__.MyClass object at 0x0000025EE62D7438>'
repr(mc)
>>
'<__main__.MyClass object at 0x0000025EE62D7438>'
class MyClass(object):
def __str__(self):
return"__str__被调用"
mc = MyClass()
mc
>>
<__main__.MyClass at 0x25ee62d7860>
print(mc)
>>
__str__被调用
str(mc)
>>
'__str__被调用'
repr(mc)
>>
'<__main__.MyClass object at 0x0000025EE62D7860>'
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__ (), 在内置函数str的内部会自动调用该方法;否则,会打印实例对象对应的类对象和实例对象在内存中的地址。
4.当调用内置函数repr创建字符串并且实参是一个实例对象时,如果在实例对象对应的类对象中实现了特殊方法 __ repr __ (), 在内置函数repr的内部会自动调用该方法;否则,会打印实例对象对应的类对象和实例对象在内存中的地址。
通常情况下,类对象的特殊方法__str__()和__repr__()的实现代码是一样的,因此当实现了其中一个后,可以把其方法名赋值给另一个方法名。
内置函数str()和repr()都返回对象的字符串表示,其区别在于:
str()的返回值是给用户看的,更加用户友好;
的返回值是给程序开发者看的,是为调试服务的。
class MyClass(object):
def __str__(self):
return"这是实例对象的字符串表达方式"
__repr__ = __str__
str("Hello,\nworld!")
##结果显示
'Hello,\nworld!'
repr("Hello,\nworld!")
##结果显示
"'Hello,\\nworld!'"