new
当使用“类名([实参])”创建实例对象时,python解释器的主要处理过程包括两大步:
1.调用特殊方法_new_()创建实例对象。
2.调用特殊方法_init_()对创建的实例对象进行初始化。
class Parent(object):
def _new_(cls, *args, **kwargs):
pass
class Child(Parent):
def _init_(self, name):
pass
id(Parent)
2753005421752
id(Child)
2753005422696
父类的_new_()被调用,其形参cls对应的实参的id:74269496
创建的实例对象的id:90380272
子类的_init_()被调用,其形参self对应实参的id:90380272
class Parent(object):
def __new__(cls, *args, **kwargs):
print("父类的__new__()被调用,其形参cls对应实参的id:", id(cls))
obj = super().__new__(cls)
print("创建的实例对象的id:", id(obj))
return obj
class Child(Parent):
def __init__(self, name):
print("子类的__init__()被调用,其形参self对应实参的id: ", id(self))
self.name = name
child = Child("Mike")
父类的__new__()被调用,其形参cls对应实参的id: 2753005426472
创建的实例对象的id: 2753022393368
子类的__init__()被调用,其形参self对应实参的id: 2753022393368
print("父类Parent的id:", id(Parent))
print("子类Child的id:", id(Child))
父类Parent的id: 2753005424584
子类Child的id: 2753005427416
getitem()、setitem()、delitem()
对于自定义类对象的实例对象,在默认情况下,是不能像列表和字典那样使用中括号语法来操作数据的。
如果想让自定义类对象的实例对象可以像列表和字典那样,使用中括号语法来操作数据,必须在自定义类对象中实现以下特殊方法:
1.getitem(self, key)
当执行操作obj[key]时,会自动调用该特殊方法。
2.setitem(self,key,value)
当执行操作obj[key] = value时,会自动调用该特殊方法。
3.delitem(self, key)
当执行操作del obj[key]时,会自动调用该特殊方法。
call()与callable()
如果在类对象中实现了特殊方法_call_(),那么就可以像调用函数一样直接调用这个类对象的实例对象,从而会自动调用特殊方法_call_()。
内置函数callable用于判断指定对象是否是可调用的。
除了函数对象是可调用的之外,对于实现了特殊方法_call_()的类对象,其实实例对象也是可调用的。
doc()与_dict_()
调用内置函数dir得到的类对象的所有属性中,有一种特殊属性叫_doc_,用于表示类对象的文档字符串。
一、什么是类对象的文档字符串(docstring)
与函数的文档字符串类似,位于类对象的第一行的字符串被称为类对象的文档字符串,通常用三个引号表示。
类对象的文档字符串是类对象的功能的简要描述。
二、访问类对象的文档字符串
通过类对象的特殊属性_doc_可以访问类对象的文档字符串。
调用内置函数help()得到的帮助信息中会包含类对象的文档字符串。
对于指定的类对象或实例对象,可以访问特殊属性_dict_获得该类对象或实例对象所绑定的所有属性和方法的字典。其中,字典中的键为属性名或方法名。
特殊属性之_slots_
Python是动态语言,所以,在创建对象之后,可以对其动态地绑定属性和方法。
如果想要对实例对象动态绑定的属性和方法的名称进行限制,可以在其对应的类对象中定义特殊属性_slots_,并给_slots_赋值一个所有元素都为字符串的列表或元组,这样,对实例对象动态绑定的属性和方法的名称就只能来自于_slots_中的元素。
默认情况下,访问实例对象的属性是通过访问该实例对象的特殊属性_dict_来实现的。
例如:访问obj.x其实访问的是obj.dict[‘x’]
在类对象中定义了特殊属性_slots_后,其实例对象就不会在创建特殊属性_dict_l了,而是为每个属性创建一个描述器,访问属性时就会直接调用这个描述器。调用描述器比访问_dict_要快,因此,在类对象中定义特殊属性_slots_可以提高属性的访问速度。
此外,在类对象中定义了特殊属性_slots_后,由于其实例对象不再创建特殊属性_dict_,同时,特殊属性_dict_是一个字典,字典的本质是哈希表,是一种用空间换取时间的数据结构,因此,在类对象中定义特殊属性_slots_可以减少内存消耗。
特殊属性_slots_只对其所在类对象的实例对象起作用,对其所在类对象的子类的实例对象是不起作用的。