乐趣区

关于python:抬抬小手学Python-类函数成员函数静态函数抽象函数方法伪装属性

十五、类函数、成员函数、动态函数、形象函数、办法假装属性

本篇博客是滚雪球学 Python 第二轮的最初一篇博客,咱们将内容持续晋升到面向对象局部,为你补充类外面的一些装璜器,学习之后,心愿你的 Python 基础知识能够更上一层楼。

15.1 类函数 @classmethod

先间接看代码,再对代码内容进行剖析与学习。

class My_Class(object):

    # 在类定义中定义变量
    cls_var = "类变量"

    def __init__(self):
        print("构造函数")
        self.x = "构造函数中的属于实例变量"

    # 类办法,第一个参数必须默认传类,个别习惯用 cls。@classmethod
    def class_method(cls):
        print("class_method 是类办法,类名间接调用")
        # 类办法不能够调用类外部的对象变量(实例变量)# print(cls.x)

# 类办法能够通过类名间接调用,也能够通过对象来调用
# 即便通过实例调用类办法,Python 主动传递的也是类,而不是实例
My_Class.class_method()
my_class_dom = My_Class()
# 通过类的对象调用
my_class_dom.class_method()

首先要把握的是类函数的定义格局,在一般函数的后面增加装璜器 @classmethod,该函数就会转换为类函数,同时函数的第一个参数默认是 cls,该变量名能够任意,倡议应用成 cls,这个是程序员之间的约定。

 @classmethod
    def class_method(cls):

同时类函数在调用的时候,能够通过 类名. 的模式进行调用,也能够通过 对象. 的模式调用,不过这两种调用都只是将类传递到了函数外部,不存在差别。
类函数不能调用实例变量,只能调用类变量,所谓 类变量 就是在类中独立申明,不在任何函数中呈现的变量。在上述代码中,类变量申明局部代码如下:

class My_Class(object):
    # 在类定义中定义变量
    cls_var = "类变量"

在 Python 中,大部分 @classmethod 装璜的函数开端都是 return cls(XXX)return XXX.__new__ () 也就是 @classmethod 的一个主要用途是作为构造函数。

15.2 动态函数 @staticmethod

先把握一个概念,动态函数不属于它所在的那个类,它是独立于类的一个独自函数,只是存放在一个类名下,先建设这个基本概念,前面学起来就简略很多了。

class My_Class(object):
    # 类变量
    cls_var = "类变量"

    def __init__(self):
        # 在构造函数中创立变量
        self.var = "实例变量"

    # 一般的对象实例函数
    def instance_method(self):
        # 能够拜访类变量
        print(self.cls_var)
        # 能够拜访实例变量
        print(self.var)
        print("实例化办法")

    @staticmethod
    def static_method():
        print(My_Class.cls_var)
        # 无法访问到实例变量
        # print(My_Class.var)
        # print(self.var)
        print("静态方法")

my_class = My_Class()
my_class.instance_method()

# 通过对象拜访
my_class.static_method()
# 类名间接拜访
My_Class.static_method()

即便批改成下述代码,也是谬误的,动态函数的第一个参数不是实例对象 self,或者能够了解为动态函数没有隐形参数,如须要传递参数,在参数列表中申明即可。

    @staticmethod
    def static_method(self):
        print(My_Class.cls_var)
        # 无法访问到实例变量
        # print(My_Class.var)
        print(self.var)
        print("静态方法")

在同一个类中,调用静态方法,应用 类名. 函数名() 的格局。

15.3 类函数与动态函数在继承类中的体现

先创立一个父类,其中蕴含两个动态函数与一个类函数。


class F(object):

    @staticmethod
    def f_static(x):
        print("静态方法,有 1 个参数")
        print(f"f_static:{x}")

    @staticmethod
    def f_static_1():
        print("静态方法,无参数")
        return F.f_static(10)

    @classmethod
    def class_method(cls):
        print("父类中的类办法")
        return F.f_static(12)

f = F()
f.f_static(11)
f.f_static_1()

f.class_method()

再编写一个 S 类继承自 F 类:

class S(F):

    @staticmethod
    def f_static(y):
        print("子类中重载了父类的静态方法")
        print(f"子类中的参数{y}")

    @classmethod
    def class_method(cls):
        print("子类中的类办法")

s = S()
s.f_static(110)
s.class_method()
S.class_method()

测试之后,根本论断如下:
如果在子类中笼罩了父类的动态函数,那调用时应用的是子类本人的动态函数,
如果在子类中没有笼罩父类的动态函数,那调用时应用的是父类的动态函数,
类函数同样遵循该规定。

如果心愿在子类中调用父类的属性或者函数,请应用 父类名. 的模式实现。

15.4 形象函数 @abstractmethod

@abstractmethod 装璜的函数为形象函数,含形象函数的类不能实例化,继承了含形象函数的子类必须笼罩所有形象函数装璜的办法,未被装璜的能够不重写。

抽象类是一个非凡的类,它的非凡之处在于只能被继承,不能被实例化,实现代码如下:

import abc

class My_Class(abc.ABC):

    @abc.abstractmethod
    def abs_method(self):
        pass

    def show(self):
        print("一般")

class M(My_Class):
    def abs_method(self):
        print('xxx')

mm = M()
mm.abs_method()

形象基类中学习还须要理解元类相干常识,在第三轮滚雪球学 Python 中将为你开展这部分内容。

15.5 办法假装属性

在 Python 面向对象的编码过程中,对象. 属性 来获取属性的值,应用 对象. 办法 () 来调用办法,通过装璜器 @property 能够将一个办法伪装成属性,从而应用 对象. 办法 没有括号的模式调用。代码非常简单:

class My_Class(object):

    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

m = My_Class("橡皮擦")
print(m.name)

这种写法最间接的利用,就是将局部属性变成只读属性,例如,上述代码,你无奈通过下述代码对 name 进行批改。

class My_Class(object):
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

m = My_Class("橡皮擦")
m.name = "擦哥擦姐"
print(m.name)

如果心愿办法假装的属性具备批改和删除性能,须要参考下述代码:

class My_Class(object):
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    @name.deleter
    def name(self):
        del self.__name

m = My_Class("橡皮擦")
m.name = "擦哥擦姐"
print(m.name)

上述代码在将 name 办法伪装成属性之后,能够通过 @name.setter@name.deleter 对同名的 name 办法进行装璜,从而实现了批改与删除性能。

所以个别应用办法假装属性的步骤是:

  1. @property 装璜器,能够用来将类中的办法伪装成属性;
  2. @办法名.setter 装璜器,在批改伪装成属性的办法值时会调用它;
  3. @办法名.deleter 装璜器,在删除伪装成属性的办法值时会调用它。

如果你感觉这个比拟麻烦,还存在一种办法假装属性的形式。应用 property 函数,原型如下

# 最初一个参数是字符串,调用 实例. 属性.__doc__ 时的形容信息
property(fget=None, fset=None, fdel=None, doc=None)

通过上述函数将办法伪装成属性的代码为:

class My_Class(object):
    def __init__(self, name):
        self.__name = name

    def del_name(self):
        del self.__name

    def set_name(self, name):
        self.__name = name

    def get_name(self):
        return self.__name
    # 将办法伪装成属性
    name = property(get_name, set_name, del_name)
m = My_Class("幻想橡皮擦")
print(m.name)
m.name = "橡皮擦"
print(m.name)

del m.name

15.6 这篇博客的总结

滚雪球学 Python 第二轮 15 篇博客在一次完结了,学 Python 咱们始终在路上,心愿本系列的课程对你的 Python 学习有所助力。

退出移动版