python 小知识 - 类全知道

简介: 类是面向对象编程的基础,是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 abc
class 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 cv2
import random
import numpy as np
import matplotlib.pyplot as plt
class 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天前
|
Python
Python-类视图和蓝图
Python-类视图和蓝图
10 2
|
4天前
|
存储 Java 数据安全/隐私保护
Python----类对象和实例对象
Python----类对象和实例对象
9 2
|
4天前
|
C++ Python
Python中的类与对象
Python中的类与对象
8 1
|
4天前
|
Python
在Python中,类的属性可以分为公有属性和私有属性
【5月更文挑战第7天】Python类包含公有和私有属性。公有属性可直接外部访问,如`person.name`,而私有属性如`_name`需通过getter/setter方法访问,如`person.getName()`和`person.setName()`。私有属性用于封装数据、隐藏实现细节,增强代码可维护性和安全性。封装能灵活修改内部实现,不影响外部;安全性防止外部非法修改数据;一致性确保所有数据操作在类内完成,简化代码并减少错误。
28 10
|
4天前
|
Python
【Python 基础】Python中的实例方法、静态方法和类方法有什么区别?
【5月更文挑战第6天】【Python 基础】Python中的实例方法、静态方法和类方法有什么区别?
|
4天前
|
存储 程序员 Python
Python中自定义类实例化数组的艺术
Python中自定义类实例化数组的艺术
11 1
|
4天前
|
程序员 Linux C++
Python中的WinForms类桌面应用程序开发
Python中的WinForms类桌面应用程序开发
25 4
|
4天前
|
Java 开发者 索引
Python基础语法:类笔记
本篇博文是把自己在学习python类的过程中自己理解和笔记,一点一点总结的写出出来,做一个总结,加深对面向对象编程的理解。
|
4天前
|
数据可视化 索引 Python
数据分享|Python用PyMC3贝叶斯模型平均BMA:采样、信息准则比较和预测可视化灵长类动物的乳汁成分数据
数据分享|Python用PyMC3贝叶斯模型平均BMA:采样、信息准则比较和预测可视化灵长类动物的乳汁成分数据
|
4天前
|
运维 算法 Shell
第六章 Python类(面向对象编程)
第六章 Python类(面向对象编程)