zoukankan      html  css  js  c++  java
  • Python的魔术方法总结

    魔术方法:再不需要程序员定义,本身就存在类中的方法就是魔术方法。

    魔术方法通常都长这样:__名字__。

    1.__str__和__repr__

    为了方便记忆看如下列子

    class Course:
        def __init__(self,name,period,price,teacher):
            self.name= name
            self.period = period
            self.price = price
            self.teacher = teacher
    
        def __str__(self):
            return 'str : %s %s %s %s' % (self.name, self.period, self.price, self.teacher)
    
        def __repr__(self):
            return 'repr : %s %s %s %s' % (self.name, self.period, self.price, self.teacher)
    course_lst = []
    python = Course('python','6 month',29800,'boss jin')
    course_lst.append(python)
    linux = Course('linux','5 month',25800,'oldboy')
    course_lst.append(linux)
    for id,course in enumerate(course_lst,1):
        # print('%s %s %s %s %s'%(id,course.name,course.period,course.price,course.teacher))
        print(id,course)
        print('%s %s'%(id,course))
        print(str(course))
        print(repr(course))
        print('%r'%course)
    __str__,__repr__

    __str__触发条件:

    1.当你打印一个对象的时候触发

    2.当你使用%格式化的时候触发

    3.str强转数据类型的时候触发

    __repr__:

    1.__repr__是__str__的备胎

    2.有__str__的时候执行__str__,没有实现__str__的时候,执行__repr__

    3.repr(obj)内置函数对应的结果是__repr__的返回值

    4.当你使用%r的格式化的时候 触发__repr__

    2.__new__

    在init之前,实例化对象的第一步是__new__创建了一个空间

    class Foo:
        def __init__(self):  # 初始化方法
            print('执行了init')
    
        def __new__(cls, *args, **kwargs):  # 构造方法
            # object.__new__(cls)
            print('执行了new')
            return object.__new__(cls)
    
    
    obj = Foo()

    创造一个对象比喻成捏小人

    new是把小人捏出来

    init给小人穿衣服

    应用:创建单例模式

    class Foo:
        __instance = None
    
        def __init__(self, name, age):  # 初始化方法
            self.name = name
            self.age = age
            self.lst = [name]
    
        def __new__(cls, *args, **kwargs):  # 构造方法
            if cls.__instance is None:
                cls.__instance = object.__new__(cls)
            return cls.__instance
    
    
    obj1 = Foo('alex', 20)
    obj2 = Foo('egon', 22)
    abc1 = Foo('cao', 33)
    print(obj1.lst, obj2.lst, abc1.lst)
    单列模式

     3.__del__

    对象的__del__是对象在被gc消除回收的时候起作用的一个方法,它的执行一般也就意味着对象不能够继续引用。

    看如下列子:

    class Foo:
        def __init__(self, name, age):
            self.name = name
            self.age = age
            self.file = open('file', mode='w')
    
        def write(self):
            self.file.write('sjahgkldhgl')
    
        def __del__(self):  # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
            # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
            self.file.close()
            print('执行del了')
    
    
    f = Foo('alex', 20)
    print(f)
    __del__

    4.__len__

    如果一个类表现得像一个list,要获取有多少个元素,就得用 len() 函数。

    要让 len() 函数工作正常,类必须提供一个特殊方法__len__(),它返回元素的个数。

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))
    print(a.__dict__)

    菲波那切数列

    # 菲波那切数列
    # class Fib(object):
    #     def __init__(self, num):
    #         a, b, L = 0, 1, []
    #         for n in range(num):
    #             L.append(a)
    #             a, b = b, a + b
    #         self.numbers = L
    #
    #     def __str__(self):
    #         return str(self.numbers)
    #
    #     # __repr__ = __str__
    #
    #     def __len__(self):
    #         return len(self.numbers)
    #
    #
    # f = Fib(10)
    # print(f)
    # print(len(f))
    菲波那切数列

    5.__eq__

    __eq__ 当判断两个对象的值是否相等时,触发此方法.

    class Staff:
        def __init__(self,name,sex):
            self.name = name
            self.sex = sex
        def __eq__(self, other):
            return self.__dict__ == other.__dict__
    alex = Staff('alex','不详')
    alex2 = Staff('alex','不详')
    alex22 = Staff('alex2','female')
    print(alex == alex2)  # alex.__eq__(alex2)
    print(alex2 == alex22)

    6.__call__

    对象后面加括号,触发执行。

    class Foo:
    
        def __init__(self):
            pass
        
        def __call__(self, *args, **kwargs):
    
            print('__call__')
    
    
    obj = Foo() # 执行 __init__
    obj()       # 执行 __call__

    7.__hash__

    # 当一个对象的类中有"__hash__"这个方法时, 那么这个对象就可以执哈希计算

    # 前提是要哈希的值是可哈希的. 哈希的不是对象, 而是可以通过对象直接执行"hash(obj)"

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __hash__(self):
            return hash(str(self.a)+str(self.b))
    a = A()
    print(hash(a))

    8.item系列

    __getitem__,__setitem,__delitem__

    class Foo:
        def __init__(self,name):
            self.name=name
    
        def __getitem__(self, item):
            print(self.__dict__[item])
    
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    
    f1=Foo('sb')
    f1['age']=18
    f1['age1']=19
    del f1.age1
    del f1['age']
    f1['name']='alex'
    print(f1.__dict__)
    item系列
     
  • 相关阅读:
    COGS 2104. [NOIP2015]神奇的幻方
    洛谷 P1387 最大正方形
    包和一些常用的模块
    模块
    模块的导入和使用
    函数迭代器与生成器
    函数的小知识
    函数的闭包和装饰器
    函数的进阶
    初识函数
  • 原文地址:https://www.cnblogs.com/caoshitong/p/10260460.html
Copyright © 2011-2022 走看看