写点什么

python 小知识 - 类全知道

作者:AIWeker
  • 2022 年 9 月 19 日
    福建
  • 本文字数:3034 字

    阅读完需:约 10 分钟

python小知识-类全知道

类是面向对象编程的基础,是 python 开发过程中需要重要掌握的知识点。


在面向对象编程中,一个对象就是一个类;一个对象有不同的属性,有不同动作或者功能项,相应的类也有不同的属性和函数。


类的作用就是将一个对象的功能和属性完整的内聚在一个类中; 如果功能和属性零散的分布在不同的地方,没有一个清晰的功能,代码结构也凌乱。

1.类的基础使用

我们来看看 python 中类的定义和使用



class Person(object): def __init__(self, name, age): self.name = name self.age = age self.interest_names = [] def add_interest(self, interest_name): self.interest_names.append(interest_name) print('{} like {}'.format(self.name, self.interest_names))
jack = Person(name='jack', age=10)jack.add_interest('football')jack.info = "haha"# jack like ['football']
jack.name, jack.age, jack.info#('jack', 10, 'haha')
复制代码


从上面可知,通过class关键字来创建类,默认的所有的类的父类为 object;


  • 通过__init__来初始化类信息,通过 self 设置可通过类的实例访问的属性

  • 类创建完,通过实例化来获取类的实例如 jack 是 Person 的实例化

  • 实例化可直接访问 self 的属性和类的方法


那 python 中类的属性或者变量有公有和私有变量?


答案是:Python 中没有禁止访问类中某一成员的保护机制;python 通过约定的方式来实现公有和私有变量,通常以下划线开头的变量和方法都不允许外部访问和修改即私有方法。


值得注意的是:以双下划线开头且以至多一个下划线结尾的成员变量或方法,会进行名称转写,如__var_, 也就是如果直接访问__var_, 会报没有这个属性的错误


class Person(object):    data = "public"        __private_ = 'private'    def __init__(self, name, age):        self.name = name        self.age = age        self.interest_names = []        self._data2 = 'not public'        self.__private = "private check"
def add_interest(self, interest_name): self.interest_names.append(interest_name) print(self.data, self._data2) print('{} like {}'.format(self.name, self.interest_names))
jack = Person(name='jack', age=10)jack.add_interest('football')print(jack._data2)print(jack.__private)
---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-26-9b8a1b0fa383> in <module>() 2 jack.add_interest('football') 3 print(jack._data2)----> 4 print(jack.__private)
AttributeError: 'Person' object has no attribute '__private'
复制代码


可见加了一个下划线的,还是可以访问的。但是如果是__private_会报错,因为 python 进行了强制转写为_Person__private,要访问需要jack._Person__private_就可以访问,这一定程度上屏蔽了外部的使用的这个变量。


可以通多dir(jack)看出 jack 实例化所拥有的变量和方法


dir(jack)['_Person__private', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_data2', 'add_interest', 'age', 'data', 'interest_names', 'name']
复制代码

2.继承

继承是类的重要特点,子类通过继承可以继承父类的方法和变量,同时也可以重写父类的方法等。上面提到默认所有的类都继承 object 大类。


下面我们来编写前面写的 Person 类的子类:工程师类 Engineer


class Engineer(Person):        def __init__(self, name, age):#         super.__init__(name, age)        super(Engineer, self).__init__(name, age)
def do_task(self, task_name): print('{} do {}'.format(self.name, task_name))
e = Engineer('john', 30)e.add_interest('program')e.do_task('do task')print(e.name, e.age)
# public not public# john like ['program']# john do do task# john 30
复制代码


从上面可知,子类继承父类的特点:


  • 可以通过 super 关键字获取父类,并进行父类的初始化

  • 子类的实例化可以直接调到父类的方法和变量


继承的好处


  • 子类是父类的扩展,不同的子类可以复用父类的方法,使得编程简洁

3.抽象类

这个小节我们来介绍一个特殊的类:抽象类;与一般的类相比,抽象类的特点:


  • 抽象类只能继承,不能实例化

  • 继承抽象类中的子类,必须重写抽象类的方法(强制的)

  • 抽象类类似接口,子类是接口的的实现

  • 抽象类要求子类必须实现里面的方法,所以经常用于框架开发中,是对某些具体的任务的抽象;比如数据处理需要经过 1.获取数据 2.数据处理 3.保存数据等步骤,可以定义数据处理的抽象,在写不同的数据处理任务时,可以按照这个流程来走,规范开发。


接着,我们来看看 python 中抽象类吧。


import abcclass Task(metaclass=abc.ABCMeta):    @abc.abstractmethod    def pre_process_data(self):        pass        @abc.abstractmethod    def do_task(self):        pass
@abc.abstractmethod def output_data(self): pass
import cv2import randomimport numpy as npimport matplotlib.pyplot as pltclass AugmentationImage(Task): def __init__(self, img_file): self.img_file = img_file self.img = None def pre_process_data(self): self.img = cv2.imread(self.img_file) h, w, c = self.img.shape print(h, w, c) start_h = random.sample(range(h//5), 1)[0] start_w = random.sample(range(w//5), 1)[0] self.img = self.img[start_h: start_h+244, start_w: start_w+244] def do_task(self, mul_=1.1): self.img = np.clip(self.img * mul_, 0, 255).astype(np.uint8) def output_data(self, output_filename='test.output.jpg'): cv2.imwrite(output_filename, self.img)
复制代码


从上面可知,


  • python 利用 abc 模块实现抽象类

  • AugmentationImage 子类继承了抽象类,来实现图像增强(随机 crop 和像素变换)

  • 必须继承抽象基类中方法(通过定义 @abc.abstractmethod)

  • 子类中实现的方法参数可以自定义变化,不一定和抽象类相同,但是名称必须相同

4.总结

本文分享了 python 中类的最基本和最重要的知识,希望对你有帮助。总结如下:


  • 如果你觉得你的代码写的太乱,一种是选择类的内聚你的功能;当然还有模块化和函数化两件法宝

  • 关键字:class 申明类,__init__来初始化类,self 定义类内和实例化可访问的方法和属性,super 获取父类,abc 实现抽象类

  • 公有和私有变量:python 没有从语法上强制变量的访问约束,都是公有的; python 采用约定方式来实现变量的访问界定,注意下划线在 python 中的特定含义;_var 一般约定为私有变量,另外注意两个前置下划线__var,python 解释器会进行强制转写。

  • 善用类的继承特性,简洁你的代码

  • 抽象类来规划你流程:抽象类的子类必须实现父类的抽象方法。

发布于: 刚刚阅读数: 4
用户头像

AIWeker

关注

InfoQ签约作者 / 公众号:人工智能微客 2019.11.21 加入

人工智能微客(aiweker)长期跟踪和分享人工智能前沿技术、应用、领域知识,不定期的发布相关产品和应用,欢迎关注和转发

评论

发布
暂无评论
python小知识-类全知道_Python_AIWeker_InfoQ写作社区