zoukankan      html  css  js  c++  java
  • python的魔术方法

    什么叫魔术方法:

    在python中定义以双下划线开头,有一些python自定义的函数,并且以双下划线为结尾的函数叫做魔法函数

    class Company(object):
        def __init__(self, employee_list):
            self.employee = employee_list
    
        def __getitem__(self, item):
            return self.employee[item]
    
        def __len__(self):
            return len(self.employee)
    
    
    company = Company(["tom", "bob", "jane"])
    
    company1 = company[:2]
    
    print(len(company))
    
    for em in company1:
        print(em)

    当中间定义了__getitem__方法,就将Company变成了一个可迭代对象,调用for循环时,python会一个一个尝试,直到报错。所以打印print(len(company1))不会报错

    __subclasshook__:

    这个魔术方法有什么用呢?

    使用__subclasshook__后只要具体类定义了与抽象类相同的方法就认为是他的子类

    import abc
     
    class A(object):
      __metaclass__ = abc.ABCMeta
     
      @abc.abstractmethod
      def say(self):
        return 'say yeah'
     
      @classmethod
      def __subclasshook__(cls, C):
        if cls is A:
          if any("say" in B.__dict__ for B in C.__mro__):
            return True
        return NotTmplementd
     
    class B(object):
      def say(self):
        return 'hello'
     
    print issubclass(B, A)   # True
    print isinstance(B(), A)  # True
    print B.__dict__      # {'say': <function say at 0x7f...>, ...}
    print A.__subclasshook__(B) # True

     3,__getattr__ 和__getattribute__区别

    # __getattr__, __getattribute__
    # __getattr__ 就是在查找不到属性的时候调用
    from datetime import date
    
    
    class User:
        def __init__(self, info={}):
            self.in fo = info
    
        def __getattr__(self, item):
            return self.info[item]
    
        # def __getattribute__(self, item):
        #     return "bobby"  这个是任何时候都会 进入的,不管是否报错
    
    
    if __name__ == "__main__":
        user = User(info={"company_name": "imooc", "name": "bobby"})
        print(user.test)
    首先调用__getattribute__。如果类定义了__getattr__方法,
    那么在__getattribute__抛出 AttributeError 的时候就会调用到__getattr__,

    4,property_test

    from datetime import date, datetime
    
    
    class User:
        def __init__(self, name, birthday):
            self.name = name
            self.birthday = birthday
            self._age = 0  # 声明不想被修改的属性
    
        # def get_age(self):
        #     return datetime.now().year - self.birthday.year
    
        @property
        def age(self):
            return datetime.now().year - self.birthday.year
    
        @age.setter
        def age(self, value):
            self._age = value
    
    
    if __name__ == "__main__":
        user = User("bobby", date(year=1987, month=1, day=1))
        user.age = 30
        print(user._age)
        print(user.age)

    其实property主要的作用就是将方法的调用伪装为一个属性的查找方式

    5,__new__和__init__区别

    class User:
        def __new__(cls, *args, **kwargs):
            print(" in new ")
            return super().__new__(cls)
    
        def __init__(self, name):
            print(" in init")
            pass
    
    
    a = int()
    # new 是用来控制对象的生成过程, 在对象生成之前
    # init是用来完善对象的
    # 如果new方法不返回对象, 则不会调用init函数
    if __name__ == "__main__":
        user = User(name="bobby")

    运行结果如下:

     in new 
     in init

    __new__在python3新式类才有的,python2.2之前中是没有的,这个方法允许我们在生成对象之前加逻辑,

    所以他传入的参数是cls类。和__init__的根本区别在于,__new__可以自定义类的生成过程的,在__init__之前,不管是传参也好,不传参也好,都需要经过__new__方法

    new 是用来控制对象的生成过程, 在对象生成之前

    init是用来完善对象的

    一般在框架中见得多。(用于元类编程)

  • 相关阅读:
    【html、CSS、javascript-9】jquery-选择器及过滤器
    【python之路40】Python 作用域
    H5缓存
    解决网络不可用--Using_Service_Workers
    跨域请求CORS
    基于node的websocket示例
    test
    函数节流
    ES6 promise
    web前端免费资源集
  • 原文地址:https://www.cnblogs.com/zhoulixiansen/p/9960245.html
Copyright © 2011-2022 走看看