zoukankan      html  css  js  c++  java
  • python 类的魔法函数 内置函数 类方法 静态方法 抽象类

    魔法函数

    __init__函数

    init函数会在实例化A这个类的时候被调用

    class A():
        def __init__(self):
            print('__init__函数')
    
    a = A()

    显示结果:

    __init__函数

    __call__函数

    
    
    class A():
        def __call__(self):
            print('__call__函数')
    
    a = A()
    a()

     显示结果:

    但类被当成一个函数的时候会被调用

    如果不写A类的call函数的话,会怎么在运行程序会怎么样呢?

    Traceback (most recent call last):
    File "D:/网站开发/oop/内置函数.py", line 6, in <module>
    a()
    TypeError: 'A' object is not callable

    A类就会报一个typeerror的错误,大致的一个就是这个类不能当成一个函数来调用

    __str__函数

    class A():
        def __str__(self):
            return '被当成了字符串'
    
    a = A()
    print(a)

    str函数是将实例化的对象可以当做一个字符串来返回。

    如果不写,再来看看会显示什么?

    class A():
        pass
    
    a = A()
    print(a)

     <__main__.A object at 0x0000017E14B05D30>

     就会把a的实例化地址显示出来

    以上这三个函数都有一个相同的特征——无需调用,但需要在特定的时间才能触发。

    其他内置函数

    __dict__函数:

    以字典的方式显示类的成员组成

    __doc__函数:

    获取文档信息——就是写在类最前面的注释

    __name__函数:

    获取类的名称,如果在模块中使用,获取模块的名称

    __bases__函数:

    获取某个类的所有父类,以元组的方式显示

    class People():
        # 实例方法
        def eat(self):
            print(self)
            print('eating')
            
        # 类方法
        @classmethod
        def play(cls):
            print(cls)
            print('playing')
            
        # 静态方法:不需要第一个参数是self或cls
        @staticmethod
        def read():
            print('reading')

    a = People()

    调用实例方法:

    a.eat()
    People.eat()

    实例方法只能用实例来调用

    无法用类来调用

    调用类方法:

    a.play()
    People.play()

    类方法可以被类调用,也可以被实例调用

    静态方法:

    a.read()
    People.read()

    静态方法可以被类调用,也可以被实例调用

    三种方法我认为最主要的不同点在于参数的问题。

    因为我们所需求的参数不同,所以会去选择不同的方法来调用。

    property

    当我们想使用的成员属性不是我们想要的属性时,使用property属性,可以使数据变成我们想要的样子。

    class People:
        def __init__(self, name):
            self.name = name
    
        def fget(self):
            self.name = self.name.lower()
            return self.name
    
        def fset(self, name):
            self.name = name + '被修改'
    
        def fdel(self):
            print('不能删除')
    
        name2 = property(fget, fset, fdel, '这个property')
    a = People('ANN')
    print(a.name)
    print(a.name2)

    显示结果:

    ANN
    ann

    当显示a的name2属性时,会触发fget函数。

    这样做就可以把所以的大写字母变成小写的字母,虽然调用函数也可以做到,但直接用以有的属性进行调用会减少代码的重复。

    a.name2 = 'bee'
    print(a.name)
    print(a.name2)

    显示结果:

    bee被修改
    bee被修改

    当想要修改name2的值时,会触发fset函数

    del a.name2

    显示结果:

    不能删除

    当想要删除name2时,触发了fdel函数

    我在这里想到的时,类的任何操作都是人来实现的,当你认为他写的函数不能满足你的开发需求时,

    你就可以去修改他的方法,无论是print还是复制操作,都是一些封装好的函数,

    而这些函数我们是可以进行修改的。

    抽象函数

    import abc
    class People(metaclass=abc.ABCMeta):
    
        # 定义一个抽象的方法
        @abc.abstractmethod
        def eat(self):
            pass
    
        #定义一个抽象类的方法
        @abc.abstractclassmethod
        def drink(cls):
            pass
    
        # 定义一个静态抽象方法
        @abc.abstractstaticmethod
        def work():
            pass

    定义一个抽象类的目的:就是为了可以规范不同人的代码

    使用抽象类注意的问题:

    • 抽象类中可以包含抽象方法,也可以包含具体方法
    • 抽象类中可以有方法,也可以有属性
    • 抽象类不能直接实例化
    • 子类可以不实现所有的抽象方法,这时子类则不能实例化。
  • 相关阅读:
    C#网络爬虫 WebUtility使用 转义字符 urlCode
    C#遍历文件夹及文件
    ThreadException
    unhandledException
    linq to object
    扩展方法
    反射常规
    字典缓存和泛型缓存
    lock和Monitor(锁对象)
    单例模式
  • 原文地址:https://www.cnblogs.com/abc23/p/10283173.html
Copyright © 2011-2022 走看看