zoukankan      html  css  js  c++  java
  • 九.python面向对象(双下方法内置方法)

    一. 内置方法

    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]=value
    
    obj = 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 22
    a=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=18
    cc.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)     执行不到
    # 1
    
    print("************************************************************************************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)
    
    # 这里是构造方法
    # <class '__main__.Da'>
    # 这里是初始化
    # 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.a1
    a=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.name
    
    s = 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  False
    first = 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=1 f1.y=2#报错 print(f1.__slots__) #f1不再有__dict__ class Bar: __slots__=['x','y'] n=Bar() n.x,n.y=1,2 n.z=3#报错
    # __slots__  省内存
    class Person(object):
         # 意思__slots__ 里面定义的属性 在实例化对象赋值时 只能使用里面定义好了的字段 不然会报错   这样会省内存
        __slots__ = ("name", "age", "speak")
    per = Person()
    per.name="哈哈哈哈"
    per.age=666
    per.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=18
    print(f1.__slots__)
    # ['name', 'age']
    f2=Foo()
    f2.name='egon'
    f2.age=19
    print(f2.__slots__)
    # ['name', 'age']
    # f1与f2都没有属性字典__dict__了,统一归__slots__管,节省内存
    print(Foo.__dict__)
    # {'__module__': '__main__', '__slots__': ['name', 'age'], 'age': <member 'age' of 'Foo' objects>, 'name': <member 'name' of 'Foo' objects>, '__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 = 222222
    print(per.age)
    
    # 张师傅
    # 动态的添加方法张师傅
    # 啊哈哈哈哈哈哈哈
    # 222222
    from types import MethodType
    
    # 创建一空类
    class Person(object):
        pass
    per = Person()
    
    per.name = "张师傅"
    print(per.name)
    
    # 动态的添加方法     必须引入一个模块
    def say(self):
        print("动态的添加方法" + self.name)
    per.speak = MethodType(say, per)
    per.speak()
    
    # 张师傅
    # 动态的添加方法张师傅
    
    print(per.__dict__)
    
    # 张师傅
    # 动态的添加方法张师傅
    # {'name': '张师傅', 'speak': <bound method say of <__main__.Person object at 0x0000025D818888D0>>}
    18 __doc__返回类的注释信息
    class Foo:
        '我是描述信息'
        pass
    print(Foo.__doc__)
    # 我是描述信息
    
    print("**********************************************")
    
    # 该属性无法继承给子类
    class Foo:
        '我是描述信息'
        pass
    class Bar(Foo):
        pass
    print(Bar.__doc__) #该属性无法继承给子类
    
    # None

     19 .__class__       __module__

     


    
    
     
     
     
  • 相关阅读:
    局域网无法访问vmware虚拟机WEB服务器解决办法
    zipimport.ZipImportError: can't decompress data; zlib not available 解决办法
    如何在win下使用linux命令
    《redisphp中文参考手册》php版
    Python关键字参数与非关键字参数(可变参数)详解
    Python与 PHP使用递归建立多层目录函数
    第一场个人图论专题
    poj_2762,弱连通
    word宏的问题
    fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
  • 原文地址:https://www.cnblogs.com/Sup-to/p/10887811.html
Copyright © 2011-2022 走看看