博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
九.python面向对象(双下方法内置方法)
阅读量:5244 次
发布时间:2019-06-14

本文共 10981 字,大约阅读时间需要 36 分钟。

一. 内置方法

1.__call__

class Da(object):     def __init__(self,a1,a2):         self.a1=a1         self.a2=a2     def cc(self):         print("我是啊哈哈哈") def __call__(self, *args, **kwargs):         print(self.a1)         print(self.a2)         print(args)         print(kwargs)         print("对象自动执行!!!!!!!!!!!!!!!!!!!1")obj=Da(11,22)print(obj.a1)print(obj.a2)print("**********************************************8")# 这是使用__call__ 方法  对象传参数自动执行obj(1,2,3,name="张三",age=555)
# 11 # 22 # **********************************************8 # 11 # 22 # (1, 2, 3) # {'name': '张三', 'age': 555} # 对象自动执行!!!!!!!!!!!!!!!!!!!1

2. __getitme__

class Da(object):     def __init__(self, a1, a2):         self.a1 = a1         self.a2 = a2     @property     def cc(self):         print("我是啊哈哈哈")     def __getitem__(self, item):         # print(item)         print(self.a1)         self.cc         return item         # return self.__dict__[itme] obj = Da(11, 22) aa = obj["k1"] print(aa)  # k1 print("*********************************") bb = obj["name", "哈哈哈", "66666"] print(bb)  # ('name', '哈哈哈', '66666') # 11 # 我是啊哈哈哈 # k1 # ********************************* # 11 # 我是啊哈哈哈 # ('name', '哈哈哈', '66666')

 3.__setitem__

# __setitem__class Da(object):    def __init__(self, a1, a2):        self.a1 = a1        self.a2 = a2    def cc(self):        print("我是啊哈哈哈")    def __setitem__(self, key, value):       print(key,value)       print(self.a1)       self.cc()       # self.__dict__[key]=valueobj = Da(11, 22)obj.cc()print("***********************")aa=obj["k1"]=588888# 我是啊哈哈哈# ***********************# k1 588888# 11# 我是啊哈哈哈

4.__delitme__

# __delitme__class Da(object):    def __init__(self, a1, a2):        self.a1 = a1        self.a2 = a2    def cc(self):        print("我是啊哈哈哈")    def __delitem__(self, key):        print(key)        # del self.__dict__[key]obj = Da(11, 22)obj.cc()print("*****************************************")del obj["lover"]print(obj.__dict__)# 我是啊哈哈哈# *****************************************# lover# {'a1': 11, 'a2': 22}
5.__iter__
# __iter__class Da(object):    def __init__(self, a1, a2):        self.a1 = a1        self.a2 = a2    def cc(self):        print("我是啊哈哈哈")    def  __iter__(self):         # return  iter([11,22,333])        yield 1        yield 22a=Da(1,2)for i in a:    print(i)# 如果 要把不可迭代对象 -》可迭代对象# 在类中定义 __iter__方法# iter 内部返回一个迭代器  生成器也是迭代器的一种  所以生成器也可以# 1# 22
6 . __getattr__
class Da(object):    num=666    def __init__(self,name):        self.name=name    def aa(self):        print(f'我的名字叫---{self.name}')    def __getattr__(self, item):            # print("我是")            print(item)cc=Da("张无忌")cc.age    #调用了一个不存的属性 才会触发 __getattr___cc.bb# age# bb
class Test(object):     def __init__(self, name):         self.name = name     def __getattr__(self, value):         if value == 'address':             return 'China' test = Test('美国') print(test.name) print(test.address) test.address = '北京' print(test.address) # 美国 # China # 北京
 
# __getattribute__  查找属性无论是否存在,都会执行 class Da(object):     def __init__(self,age):         self.age=age     def __getattribute__(self, item):           print(item,"嗡嗡嗡嗡嗡嗡嗡嗡嗡嗡嗡嗡嗡嗡嗡")           print("********************")           # print(self.age) aa=Da(55) aa.bbbbbbbb print(aa.age)
class Test(object):     def __init__(self, name):         self.name = name     def __getattribute__(self, value):         if value == 'address':             return 'China' test = Test('上海') print(test.name) print(test.address) test.address = '北京' print(test.address) # None # China # China
 7. __setattr__
class Da(object):    num=666    def __init__(self,name):        self.name=name            def aa(self):        print(f'我的名字叫---{self.name}')    def __setattr__(self, key, value):        self.__dict__[key] = value        print(key,value)cc=Da("张无忌")                #  __setattr__   设置属性时会促发 __setattr__cc.age=18cc.hod="篮球"print(cc.__dict__)# name 张无忌# age 18# hod 篮球# {'name': '张无忌', 'age': 18, 'hod': '篮球'}
8.__delattr__
# __delattr__  删除一个会促发这个方法class Fa(object):    def __init__(self, name):        self.name = name    def __setattr__(self, key, value):        if type(value) is str:            print("执行__setattr__方法", key, value)            self.__dict__[key] = value        else:            print("必须是字符串")    def __delattr__(self, item):        print("执行 __delattr__ 方法", item)a4 = Fa("张三")a4.age = "25岁"a4.sex = "男"a4.shenggao = 188  # type 是数字就添加不进去print(a4.__dict__)del a4.name                        # __delattr__  删除一个会促发这个方法"""执行__setattr__方法 name 张三执行__setattr__方法 age 25岁执行__setattr__方法 sex 男必须是字符串{'name': '张三', 'age': '25岁', 'sex': '男'}执行 __delattr__ 方法 name"""
9. __new__    __init__
class Da(object):    def __init__(self, a1, a2):        self.a1 = a1        self.a2 = a2    def cc(self):        print("我是啊哈哈哈")    def __new__(cls, *args, **kwargs):        print(1)obj = Da(11, 22)# print(obj.a1)     执行不到# 1print("************************************************************************************88")# 注意 在类中 使用__init__初始化函数前    是自动默认会执行__new__构造方法# 虽然我们不用添加__new__  但是我们要知道  在使用 __init__初始化 前 python 内部就自动调用了 __new__构造方法class Da(object):    def __init__(self, a1, a2):        print("这里是初始化")        self.a1 = a1        self.a2 = a2    def cc(self):        print("我是啊哈哈哈")    def __new__(cls, *args, **kwargs):        print("这里是构造方法")        print(cls)        return object.__new__(cls)  #  构造方法必须返回   object.__new__(cls)  才能执行__init__初始化对象obj = Da(11, 22)print(obj.a1)# 这里是构造方法# 
# 这里是初始化# 11

# __new__ 的作用

# # 1、__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。
# # 假如我们需要一个永远都是正数的整数类型,通过集成int,我们可能会写出这样的代码。
#
#
# # 3、__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))
# # __new__出来的实例,或者直接是object的__new__出来的实例
#
# # 4、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值

 10 . __add__
# __add__# 对象可以相加   加减  乘  除class Da(object):    def __init__(self, a1, a2):        self.a1 = a1        self.a2 = a2    def cc(self):        print("我是啊哈哈哈")    def __add__(self, other):        return self.a1+other.a1a=Da(1,2)b=Da(100,20)print(a+b)# 101
11. __del__
# 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作# (例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。# 析构函数 :__del__()释放对象自动调用class person(object):    def run(self):        print("run")    def __init__(self, name, age, height, weight):        self.name = name        self.age = age        self.height = height        self.weight = weight    def __del__(self):       print("这里是析构函数") per = person("张三", 25, 300, 100)# 释放对象       就相当于删除了    就不能访问了   这是手动释放del per# 在函数里定义的对象会在函数结束时自动释放(删除)  可以减少内存浪费空间def fun():    per2 = person("李四", 1000, 2000, 30000)    print(per2.name)fun() #这里是析构函数
# 李四 # 这里是析构函数
# __del__也称之为析构方法 # # __del__会在对象被删除之前自动触发 class People:     def __init__(self, name, age):         self.name = name         self.age = age         self.f = open('test.txt', 'w', encoding='utf-8')     def __del__(self):         print('run======>')         # 做回收系统资源相关的事情         self.f.close() obj = People('egon', 18) del obj  # del obj会间接删除f的内存占用,但是还需要自定制__del__删除文件的系统占用 print('主') # run======> # 主
 
 13. __len__
# __len__  和 len配合使用class Students(object):    def __init__(self, *args):        self.names = args    def __len__(self):        return len(self.names)aa=Students("111",222)print(aa)print(len(aa))# 2
14. __str__
# __str__()函数的作用:# 不知道大家再写程序是,打印一个实例化对象时,打印的其实时一个对象的地址。而通过__str__()函数就可以帮助我们打印对象中具体的属性值,或者你想得到的东西。## 因为再python中调用print()打印实例化对象时会调用__str__()如果__str__()中有返回class ss:    def __init__(self,age,name):        self.age = age        self.name = name    def __str__(self):        return str(self.age)+",,wozenmezhemeshuai,,"+self.names = ss(21,'aitebao')print(s)# 21,,wozenmezhemeshuai,,aitebao
 15. __hash__
# __hash__  hash() 用于获取取一个对象(字符串或者数值等)的哈希值。class F(object):      def __init__(self,name,sex):          self.name=name          self.sex=sex      def __hash__(self):          return  hash(self.name+ self.sex)a=F("张三","男")b=F("张三","1111")print(hash(a))print(hash(b))
16.__eq__
# 如果不实现__eq__方法,那么自定义类型会调用默认的__eq__方法, 通过默认方法进行比较的相等条件相当严格,只有自己和自己比才会返回True,表现如下# __eq__# class B(object):#     def __int__(self,name):#         self.name=name#     def __eq__(self,other):#         if self.name==other.name:#             return  True# c1=B("张三")# c2=B("李四")class Item:  def __init__(self, name):      self. name=  name  def __eq__(self, other):     if self. name== other. name:         return True     else:         return  Falsefirst = Item('hello')second = Item('hello')print(first == second) # True
17.__slots__
__slots__是一个类变量,变量值可以是列表,元祖,或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)使用点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立的)
 
  • 字典会占用大量内存,如果你有一个属性很少的类,但是有很多实例,为了节省内存可以使用__slots__取代实例的__dict__

  • 当你定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个字典,这跟元组或列表很类似。在__slots__中列出的属性名在内部被映射到这个数组的指定小标上。使用__slots__一个不好的地方就是我们不能再给实例添加新的属性了,只能使用在__slots__中定义的那些属性名。

class Foo:    __slots__='x'f1=Foo()f1.x=1f1.y=2#报错print(f1.__slots__) #f1不再有__dict__class Bar:    __slots__=['x','y']    n=Bar()n.x,n.y=1,2n.z=3#报错
# __slots__  省内存class Person(object):     # 意思__slots__ 里面定义的属性 在实例化对象赋值时 只能使用里面定义好了的字段 不然会报错   这样会省内存    __slots__ = ("name", "age", "speak")per = Person()per.name="哈哈哈哈"per.age=666per.speak=4444444# 意思就是只能添加__slots__里面定义的属性#per.aa=6666   #会报错因为__slotl__里面没有定义# 使用__slots__时 __dict__ 也不能用print(per.__slots__)print(Person.__slots__)print("*************************************************************************8")class Foo:    __slots__=['name','age']f1=Foo()f1.name='alex'f1.age=18print(f1.__slots__)# ['name', 'age']f2=Foo()f2.name='egon'f2.age=19print(f2.__slots__)# ['name', 'age']# f1与f2都没有属性字典__dict__了,统一归__slots__管,节省内存print(Foo.__dict__)# {'__module__': '__main__', '__slots__': ['name', 'age'], 'age': 
, 'name':
, '__doc__': None}
from types import MethodType# 创建一空类class Person(object):    # 想添加什么属性就写在里面    __slots__ = ("name", "age", "speak")per = Person()per.name = "张师傅"print(per.name)# 动态的添加方法     必须引入一个模块def say(self):    print("动态的添加方法" + self.name)    print("啊哈哈哈哈哈哈哈")per.speak = MethodType(say, per)per.speak()"""思考: 如果我们想要 限制实例的属性怎么办比如 只允许给对象添加name age height 特定的属性解解方法:      定义类的时候 定义一个特殊的属性 (__slots__)可以限制动态属性的添加      """per.age = 222222print(per.age)# 张师傅# 动态的添加方法张师傅# 啊哈哈哈哈哈哈哈# 222222
from types import MethodType# 创建一空类class Person(object):    passper = Person()per.name = "张师傅"print(per.name)# 动态的添加方法     必须引入一个模块def say(self):    print("动态的添加方法" + self.name)per.speak = MethodType(say, per)per.speak()# 张师傅# 动态的添加方法张师傅print(per.__dict__)# 张师傅# 动态的添加方法张师傅# {'name': '张师傅', 'speak': 
>}
18 __doc__返回类的注释信息
class Foo:    '我是描述信息'    passprint(Foo.__doc__)# 我是描述信息print("**********************************************")# 该属性无法继承给子类class Foo:    '我是描述信息'    passclass Bar(Foo):    passprint(Bar.__doc__) #该属性无法继承给子类# None

 19 .__class__       __module__

 

 
 

 

 
 

 

 

 

 

 

转载于:https://www.cnblogs.com/Sup-to/p/10887811.html

你可能感兴趣的文章
【动态规划】skiing
查看>>
java定时器的使用(Timer)
查看>>
ef codefirst VS里修改数据表结构后更新到数据库
查看>>
boost 同步定时器
查看>>
[ROS] Chinese MOOC || Chapter-4.4 Action
查看>>
简单的数据库操作
查看>>
iOS-解决iOS8及以上设置applicationIconBadgeNumber报错的问题
查看>>
亡灵序曲-The Dawn
查看>>
Redmine
查看>>
帧的最小长度 CSMA/CD
查看>>
xib文件加载后设置frame无效问题
查看>>
编程算法 - 左旋转字符串 代码(C)
查看>>
IOS解析XML
查看>>
Python3多线程爬取meizitu的图片
查看>>
树状数组及其他特别简单的扩展
查看>>
zookeeper适用场景:分布式锁实现
查看>>
110104_LC-Display(液晶显示屏)
查看>>
httpd_Vhosts文件的配置
查看>>
php学习笔记
查看>>
普通求素数和线性筛素数
查看>>