Python-内置的__xxx__()含义
面向对象的编程思想
编程经历的几个阶段:从最开始的需要什么数据和功能,就直接写。到函数,将功能写到一起。但是和数据还是分开的,数据和功能并没有很强的耦合性,都是一个个独立的个体。所以演变到面向对象,面向对象的思想是将数据和功能整合到一起。
将数据和功能整合到一起的方式有很多,只要将数据和功能整合到一起,就属于面向对象的范畴。如:将数据和功能放在一个文件中,使用的时候,导入这个文件。甚至将数据和功能放在列表/字典中。只要实现了将数据和功能放在一起,那么就可以说是面向对象。
面向对象指的是一种编程思想,不仅仅指的是某种语法。语法是一个语言特有的,不通语言,其语法不尽相同,而编程思想是所以语言都通用的。
在实例 通过__new__() 被创建之后,返回调用者之前调用。其参数与传递给类构造器表达式的参数相同。一个基类如果有__init__方法,则其所派生的类如果也有__init__方法,就必须显式地调用它以确保实例基类部分的正确初始化;例如: super().__init__([args...]).
因为对象是由 __new__() 和__init__ 协作构造完成的 (由 __new__() 创建,并由 __init__定制),所以 __init__ 返回的值只能是 None,否则会在运行时引发TypeError
即:
1、__init__()是在__new__()之后执行的
2、传递给__new__()的参数和传递给__new__()一样
3、若父类有__init__方法,子类也有__init__(),那么子类就必须调用父类的__init__(),在子类的__init__()里面调用
4、__init__()返回值必须是None(不写return也是返回None)
__del__()
__del__():创建一个对象时,python解释器默认会调用__init__()方法初始化,而删除一个对象时,python解释器默认调用__del__方法。但在python中,很少会直接销毁对象,而是通过gc(垃圾回收机制)自动回收内存。若需手动删除,应调用del关键字删除。所以,不管手动删除,还是gc自动回收,都会触发__del__的执行
演示代码
import time class Book: def __init__(self,name): self.name = name def __del__(self): print('当前实例为:%s,id为:%s'%(self.name,id(self))) print('python解释器正在回收对象:%s' %self.name) time.sleep(2) book_1 = Book(name='hlm')
当代码执行完毕,会自动触发__del__的执行
del和__del__的区别
del x并不会直接调用x.__del__(),而是将x的计数减一,x.__del__会在应用计数为0的时候被触发。并且定义了__del__的实例无法被python的垃圾回收机制收集,所以不建议自定义__del__。
__str__()
通过str(object),或format(),或print()调用以生成一个对象的字符串表示,返回值必须是字符串对象
如,在drf中,将模型表注册到admin中,通过自定义__str__方法,返回值就在admin页面上显示
class User(AbstractUser): mobile = models.CharField(max_length=32, unique=True) # 手机号唯一性约束 icon = models.ImageField(upload_to='icon', default='icon/default.png') # 存的是一个地址,还要在settings.py中配置路径 def __str__(self): return self.username
__call__()
python中一切皆对象,此方法会在实例作为一个函数被加括号调用时被调用,若定义了此方法,则t(arg1,arg2,...)就相当于t.__call__(arg1,arg2,...)
关于可调用对象,常用的函数和类都属于可调用对象,但凡可以加括号使用的,都称作可调用对象,判断对象是否为可调用对象用callable函数
一个类要变成一个可调用对象,只需要定义__call__即可
class Test: def __call__(self, *args, **kwargs): print('%s叫你' % args) print('%s叫你' % kwargs.get('name')) t = Test() # 实例化 print(callable(t)) # True t('tom', name='jerry') # 对象加括号,当做函数调用
class Book:
name = 'are you ok?' # 定义一个类属性
comment = 'nong sa lei'
def func(self): # 定义一个类方法
print('what are you doing?')
print('i am fine, thank you!') # 执行就打印,类体代码是在定义时执行的
# 实例化对象
book_1 = Book()
book_2 = Book()
# 修改对象属性
book_1.name = 'enheng?'
book_2.name = 'nongsalei?'
这样就产生了一个问题,代码的重复度很高,所以可以把相同代码写成一个初始化对象的函数的方式来简化代码
# 通过函数来简化代码
def init(obj, name, comment): # 传入对象和参数
obj.name = name
obj.price = comment
return obj # 将初始化的对象返回
这样写,是可以的,不过和类的关联性较低,关联性不大,所以可以直接将这个函数写到类中,然后实例化对象的时候去调用它
同时,python也支持这一写法,所以推出了__init__()内置方法,在实例化对象的时候,自动初始化,无需手动调用
# 通过__init__()的方式写一个类 class Book: def __init__(self, name, comment='n'): self.name = name self.comment = comment def func(self): print('what are you doing?') print('i am fine, thank you!') # 这样实例化对象 book_1 = Book(name='are you ok?',comment='nong sa lei?') # # 修改属性和之前一样
浙公网安备 33010602011771号