zoukankan      html  css  js  c++  java
  • Python第六天-面向对象

    使用函数模拟定义类

    def Person(name, age):
        def run(self):
            print("{name} is running".format(name=self["name"]))
    
        def init():
            return {
                "name": name,
                "age": age,
                "run": run
            }
    
        return init()
    
    
    # 模拟创建一个对象
    lisi = Person("lisi", 24)
    # 模拟调用对象的方法
    lisi["run"](lisi)
    
    

    定义类

    class Person():
        def __init__(self, name):
            self.name = name
    
        def run(self):
            print("{} is running".format(self.name))
    
    
    xiaoming = Person("xiaoming")
    xiaoming.run()
    

    使用class 声明类,默认继承object类,实例化对象是默认调用__init__方法,xiaoming.run() 就类似于 Person.run(xiaoming),self参数就是的当前对象。

    对象属性和类属性

    class Person(object):
        NAME = "lisi"
    
        def __init__(self, name):
            self.name = name
    
        def run(self):
            print("{} is running".format(self.name))
    
        def of():
            return Person(Person.NAME)
    
    
    xiaoming = Person("xiaoming")
    xiaoming.run()
    
    print(Person.NAME)
    print(Person.__dict__)
    print(Person.of().__dict__)
    

    name属性为对象属性,NAME为类属性,函数都是类的属性,当对象调用函数时,在当前对象中找不到这个属性函数,会去类中找,相当于当前作用域和上级作用域的关系。

    对象方法,类方法,静态方法

    class Circular():
        PI = 3.14
    
        def __init__(self, radius):
            self.radius = radius
    
        @property
        def perimeter(self):
            return 2 * self.PI * self.radius
    
        def calcPerimeter(self):
            return 2 * self.PI * self.radius
    
        @staticmethod
        def calcArea(radius):
            return Circular.PI * radius * radius
    
        @classmethod
        def area(cls, radius):
            return cls.PI * radius * radius
    
    
    circular = Circular(2)
    print(circular.perimeter)
    print(circular.calcPerimeter())
    print(Circular.calcArea(2))
    print(Circular.area(2))
    

    @property将方法装饰为一个属性,@staticmethod表示静态方法,通过类调用,@classmethod表示类方法,也通过类调用

    类继承

    import abc
    
    class Runnable(metaclass=abc.ABCMeta):
        @abc.abstractmethod
        def run(self):
            pass
    
    
    class Cat(Runnable):
    
        def run(self):
            print("Cat is running...")
    
    
    class Dog(Runnable):
    
        def run(self):
            print("Dog is running...")
    
    
    cat = Cat()
    cat.run()
    dog = Dog()
    dog.run()
    
    

    定义一个类似于java中接口的父类,并且将方法定义为抽象方法,这个子类就必须重写这些方法。

    类的内置方法

    class Animal():
        """
        类的内置方法
        """
    
        """
        访问属性首先会调用本方法,会检测__dict__中是否包含属性 print(obj.item)
        """
    
        def __getattribute__(self, item):
            return super().__getattribute__(item)
    
        """
        调用__getattribute__方法没有获取到时调用,print(obj.item)
        """
    
        def __getattr__(self, item):
            return "default"
    
        """
        设置对象属性时调用,obj.key=value
        """
    
        def __setattr__(self, key, value):
            return super().__setattr__(key, value)
    
        """
        删除对象属性时调用 del obj.item
        """
    
        def __delattr__(self, item):
            return super().__delattr__(item)
    
    """
        以obj[item]方式访问属性时被调用
        """
    
        def __getitem__(self, item):
            return self.__getattribute__(item)
    
        """
        obj[item] = value
        """
    
        def __setitem__(self, key, value):
            self.__setattr__(key, value)
    
        """
        del obj[item]
        """
    
        def __delitem__(self, key):
            self.__delattr__(key)
    
        """
        str(obj)被调用 返回对象的字符串形式
        """
    
        def __str__(self):
            return "this is Animal"
    
        """
        repr(obj)被调用 类似__str__ 控制台打印
        """
    
        def __repr__(self):
            return self.__str__()
    
        """
        len(obj)被调用
        """
    
        def __len__(self):
            return len(self.__str__())
    
        """
        format(obj)被调用
        """
    
        def __format__(self, format_spec):
            return "this is Animal"
    
        """
        手动del obj或被gc回收时被调用
        """
    
        def __del__(self):
            print("del")
            pass
    
        """
        obj()被调用
        """
    
        def __call__(self, *args, **kwargs):
            pass
    
        """
        next(obj)被调用,返回迭代器的下一个元素
        """
    
        def __next__(self):
            pass
    
        """
        iter(obj)被调用,返回一个迭代器对象
        """
    
        def __iter__(self):
            return iter([])
    
    class Person():
        __slots__ = ["name", "age"]
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    
    p = Person("lisi", 23)
    p.pwd = "as"
    print(p.pwd)
    

    定义了__slots__属性,对象就没有__dict__属性了,就限制了对象的属性字典,不能增加新的属性。

    描述符

    class Desc():
    
        def __set__(self, instance, value):
            print("set")
    
        def __get__(self, instance, owner):
            print("get")
    
        def __delete__(self, instance):
            print("del")
    

    一个类定义了以上3个方法任意一个就是一个描述符,只定义get为非数据描述符,定义了set,del为数据描述符

    class TestDesc():
        desc = Desc()
    
    
    test_desc = TestDesc()
    test_desc.desc = "a"
    print(test_desc.desc)
    

    描述符必须定义为类属性,当调用test_desc.desc = "a"时,实际上会转换成TestDesc.dict['desc '].get(test_desc, TestDesc)

    属性查询优先级总结

    1. getattribute(), 无条件调用

    2. 数据描述符:由 ① 触发调用 (若人为的重载了该 getattribute() 方法,可能会导致无法调用描述符)

    3. 实例对象的字典(若与描述符对象同名,会被覆盖)

    4. 类的字典

    5. 非数据描述符

    6. 父类的字典

    7. getattr() 方法

  • 相关阅读:
    jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
    jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
    jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
    jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
    jQuery 源码分析(二十) DOM操作模块 插入元素 详解
    jQuery 源码分析(十九) DOM遍历模块详解
    python 简单工厂模式
    python 爬虫-协程 采集博客园
    vue 自定义image组件
    微信小程序 image组件坑
  • 原文地址:https://www.cnblogs.com/strongmore/p/13709033.html
Copyright © 2011-2022 走看看