面向对象的内功心法

这里分为两个部分,内置方法和内置函数。当然,内置方法是特别的多的,这里只是冰山一角,但一定都是最最能用的到的。这的内置函数也会讲解一些特殊用法,都是减少代码的,提升代码质量。

从python深处说,应该先聊聊内置方法:

__new__(cls,*args,**kwd)  构造方法, 可以开辟处一块内存空间
__init__(self)        初始化对象,创建对象的时候,可以存一些对象初始的属性,
                 在实例化的时候,就会自动的运行。
**这里解释一下类的运行过程:
  在定义类的时候,就会开辟处一个空间,这个空间是给这个类的,在这个命名空间中,有静态属性,动态属性
  类方法@classmethod,静态方法@staticmethod,伪装属性方法@property,双下方法,当然__init__方法,
  重点就在这个__init__上,在实例化一个对象的时候,首先运行一个__new__,开创一个空间,因为这时,在有
  对象之前,所以不用self,而是cls。然后在__init__中,以字典的形式,添加一些属性。这时,把这片空间的内
  存地址给到self,这时,在把self的地址通过实例化后,就赋值给了对象。当然,在这片空间中,还有一个类指针,
  会把这片空间指向了类命名空间。在调用属性或方法时,先从自己的空间里找,如果找不到,就去类的空间里找。再
  找不到,就报错。
__call__(self,*args)     把对象作为函数调用时候运行,对象加括号,就会自动调用
                 类中__call__方法下的代码。
__str__             print(obj)\str(obj)\"%s"%obj 都会触发__str__
__repr__ repr(obj)\"%r"%obj  都会触发__repr__,这个方法也是__str__的备胎
__del__(self)     析构方法 释放对象,在对象被删除之前调用
__eq__(self,other)      判断self对象的属性是否等于other对象的属性
                 a.name==b.name
                 def __eq___(self,other):
                    if self.name ==other.name:
                      return True
                    return Flase
__hash__            hash(obj) 会触发
__getattr__          获取属性的值。
__setattr__          设置属性的值。修改或增加都会触发。
__delattr__          删除name的属性。删除会触发
__getattribute__       功能和getattr相似,但是效果比较好一些。
以上都时和使用命名空间加点的取值方式有关的。
值得注意的是,getattr如果取的是存在的属性,会取出其中的值,但是,如果是不存在的属性,就会调用getattr方法
第二点要注意的是,很多人会在调用方法的时候,陷入递归锁的陷阱,应该用self._dict_[]的方式来完成。

 最有用的自省--------反射

hasattr()是否存在
getattr()获取属性的值,或者是方法的地址
setattr()创建或修改值的时候
delattr()删除属性
类\对象\模块\实际上都有自己的命名空间,实际上,反射都是一个逻辑 值=getattr(命名空间,字符串) 如果字符串是属性,那么值就是属性,如果字符串是
方法,结果就是函数的内存地址。
小重点:类的命名空间:静态方法,类方法,静态方法,普通方法,property方法。这些都是可以变成私有的。
    对象的命名空间:对象的属性
如何调用本文件中的变量名?
from sys import modules:
  ret = getattr(modules[__name__],string)

有些好玩的装饰器

伪装成属性的方法
@property
class Person:
def __init__(self,name):
self.__name = name # 不让外面随便修改

@property #将这个方法变成一个属性。简单的说,就是不用再用 对象.方法() 这样的形式来调用了。就是用 (对象|类名).方法 连括号都不用加了
def name(self):
return self.__name

alex = Person('孙悟空')
print(alex.name)

小升级的地方
修改伪装成属性的方法
class Person:
def __init__(self,name):
self.__name = name # 不让外面随便修改 可以写一个接口,让外面来调用

@property
def name(self):
return self.__name

@name.setter # 之前必须有一个同名的方法被property装饰过,这里的name必须是前面的name是相互呼应的
def name(self,new_name): #之前必须有一个同名的方法被property装饰过,这里的name必须是前面的name是相互呼应的
if type(new_name) is str:
self.__name = new_name

@name.deleter #之前必须有一个同名的方法被property装饰过,这里的name必须是前面的name是相互呼应的
def name(self): #之前必须有一个同名的方法被property装饰过,这里的name必须是前面的name是相互呼应的
del self.__name

def set_name(self,new_name):
if type(new_name) is str:
self.__name = new_name
孙悟空 = Person('孙悟空')
print(孙悟空.name)
孙悟空.set_name(“猪八戒”)
print(孙悟空.name)
#相当于 孙悟空.name = '猪八戒'
print(孙悟空.name)
del 孙悟空.name # 只是相当于调用被deleter装饰的方法,并不相当于删除name属性
print(孙悟空.name)

  

剩下两个就是
类方法的装饰器
@classmethod
用法没有特别,就是不用对象来调用了,可以用类来调用,差别就在于传入的参数不是self了而是cls 不过,还是可以用对象来调用的,类当然也可以
静态方法
@staticmethod
用法没特别,就是赤裸裸想把这个函数写入类中,既不是操作对象的属性,又没有操作类的方法,所以,什么都不用传了!类可以调用,对象也可以调用。

 

扫描二维码关注公众号,回复: 4264171 查看本文章

猜你喜欢

转载自www.cnblogs.com/ycxiaolaba/p/10029506.html
今日推荐