• 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() 方法

  • 相关阅读:
    oracle客户端plsql设置字符集
    命令导入导出oracle库
    java初级开发一系列的工具安装配置
    docker学习笔记-5.数据共享
    docker学习笔记-4.harbor
    flask学习笔记2
    socket编程学习
    docker学习笔记-3.docker镜像制作
    docker学习笔记-2.docker镜像制作
    docker学习笔记-1.docker基础
  • 原文地址:https://www.cnblogs.com/strongmore/p/13709033.html
Copyright © 2020-2023  润新知