python 类的魔法函数 内置函数 类方法 静态方法 抽象类 魔法函数 其他内置函数 property 抽象函数

__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

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

使用抽象类注意的问题:

  • 抽象类中可以包含抽象方法,也可以包含具体方法
  • 抽象类中可以有方法,也可以有属性
  • 抽象类不能直接实例化
  • 子类可以不实现所有的抽象方法,这时子类则不能实例化。