面向对象05

当使用“类名([实参])”创建实例对象时,python解释器的主要处理过程包括两大步:
1、调用特殊方法__new__()创建实例对象
首先会查找类对象是否实现了特殊方法__new__(),如果没有实现,则去父类中一次查找,直到类对象object

2、调用特殊方法__init__()对创建的实例对象进行初始化
new()返回的实例对象会作为实参被自动传递给__init__()的第一个形参self

class Parent(object):
   def __new__(cls,*args,**kwargs):
       pass
   
class Child(Parent):
   def __init__(self,name):
       pass
类和实例对象都有地址
id(Parent)
id(Child)

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("子类的__new__()被调用,其形参cls对应实参的id:",id(self))
       self.name = name
child = Child("Mike")

print("父类Parent的id:",id(Parent))#2908266608680
print("子类Child的id:",id(Child))#2908266605848
print("创建的实例对象的id:",id(child))#2908287139120

对于自定义类对象的实例对象,在默认情况下,是不能像列表和字典那样使用中括号语法来操作数据
必须定义自定义类对象中实现以下特殊方法:
1、getitem(self,key)
当执行操作obj[key]时,会自动调用该特殊方法
2、setitem(self,key,value)
当执行操作obj[key] = value时,会自动调用该特殊方法
3、delitem(self,key)
当执行操作del obj[key]时,会自动调用该特殊方法

class MyDict(object):
    def __init__(self):
        self.data = {}
    def __getitem__(self,key):
        return self.data[key]
    def __setitem__(self,key,value):
        self.data[key] = value
    def __detitem__(self,key):
        del self.data[key]

md = MyDict()
md["one"] = 18
md["two"] = 32
print(md.data)
del md["two"]

如果在类对象中实现了特殊方法__call__(),那么就可以像调用函数一样直接调用这个类对象的实例对象,从而会自动调用特殊方法__call__()

class mycall(object):
    def __call__(self,*args,**kwargs):
        print(args,kwargs)
mc = mycall()
mc()
mc(1,2,x = 3,y = 4)

内置函数callable用于判断指定对象是否是可调用的
除了函数对象是可调用的之外,对于实现了特殊方法__call__()的类对象,他的实例对象也是可调用的

(一)什么是类对象的文档字符串
位于类对象的第一行的字符串
(二)访问类对象的文档字符串
通过类属性的__doc__
调用内置函数help()得到的帮助信息中会包含类对象的文档字符串

class MyClass(object):
	'''这是类对象的文档字符串
	1
	2
	3
	'''
	pass
	
print(MyClass.__doc__)

输出:
	'''这是类对象的文档字符串
	1
	2
	3
	'''
	
print(help(MyClass)

对于指定的类对象或实例对象,可以访问特殊属性__dict__获得该类对象或实例对象所绑定的所有属性和方法的字典,其中,字典的键为属性名或方法名

python是动态语言,所以在创建对象之后,可以对其动态地绑定属性和方法
如果想要对实例对象动态绑定的属性和方法的名称进行限制,可以在其对应的类对象中定义特殊属性__slots__,并给__slots__复制一个所以元素都为字符串的列表或元组,这样,对实例对象动态绑定的属性和方法的名称就只能来自于__slot__中的元素

class Myclass(object):
	__slots__ = ('attr1','do_sth1')
	
mc = MyClass()
mc.attr1 = 18
mc.attr2 =56#报错
def do_sth2(self):
	print('do_sth2')
mc.do_sth2 = MethodType(do_sth2,mc)#报错

MethodType(a,b)#将函数a绑定给实例对象b
特殊属性__slots__只对其所在类对象的实例对象起作用,对其所在的类对象的子类的实例对象是不起作用的

class ChildClass1(MyClass):
	pass
	
mc_child = ChildClass1()
mc_child.attr3 = 66
print(mc_child.attr3)#不报错

如果子类也定义了特殊属性__slots__,那么子类的实例对象可以动态绑定的属性和方法的名称为子类的__slots__加上父类的__slots__

内置函数len()的实参在默认情况下不能是自定义类对象的实例对象
必须定义自定义类对象中实现特殊方法__len__:

(i*i for i in range(8))#生成器表达式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值