ExASIC
分享让工作更轻松

Python的类(一):入门

为什么要学类(Class)

我们知道Python中一切都是对象,但我们之前的脚本中似乎不需要知道什么是类,什么是对象,看起来就是一个个函数。那么我们为什么还要学面向对象(类)的编程呢?

首先,阅读python库的源码。

很多时候,由于文档不全,或者报库里的Error时,这时就需要自己深入研究库的源代码。而一般的库都是类的结构。

其次,使用第三方的python框架。

比如你需要搭建一个简单的web应用,例如,部门内部的在线投票网页,又或者基于web的IC项目进度管理,你很可能选用Django。如果没有类的概念,那么下面的代码将很难理解。

from django.http import HttpResponse
def hello(request):
    return HttpResponse("Hello world!")

再次,写自己的框架。

有人表示怀疑,“我们做IC的工程师还需要写框架?”

我举个例子,比如我们想写一个通用的仿真脚本,在调用仿真器之前也许需要做一些RTL预处理。很可能你的RTL里会嵌入一些python或perl的代码,用于RTL自动生成。一般来说仿真脚本里写一个预处理函数preprocess()就可以了。

但如果前端设计工程师在RTL里嵌入了一些自定义规则的代码,那么预处理函数就需要增加新的Feature。如果直接修改仿真脚本可能不太合适,因为在其它项目中不需要这个新的Feature。

于是,我们联想到了SystemVerilog sequence的pre_start(),随机化的pre_randomize()。UVM环境里的解决方案是在派生类里重写pre_start()和pre_randomize()。所以我们的通用仿真脚本也可以采用这种模式。

类,其实我们并不陌生。IC验证工程师天天在与SystemVerilog(VMM、UVM)的类打交道。

如何学习

我们学过C++,也许你学过Java,又或者你是做验证的,学UVM。那么学习python的类就简单多了,因为我们已经知道了大部分的面向对象的术语,比如OOP、类、实例化、对象、属性(成员变量)、方法(成员函数)、基类、派生、重载、虚函数等。所以我们只需要过一遍python类的语法即可,找出与其它语言的差异

Hello world!

我们直接上一个例子simReport.py:假如我们在IC验证时需要统计仿真结果,需要统计Testcase总数,并显示每个Case的结果。(这个例子仅用来介绍python class的语法)

class simReport:
    """ This an example of simulation report """

    totalCount = 0

    def __init__(self, name, result):
        self.name = name
        self.result = result
        simReport.totalCount = simReport.totalCount + 1

    def showResult(self):
        print("Total: {}".format(simReport.totalCount))
        print("{}: {}".format(self.name, self.result))

if __name__ == '__main__':
    simRptSvr1 = simReport("testcase1", "pass")
    simRptSvr1.showResult()
    simRptSvr2 = simReport("testcase2", "fail")
    simRptSvr2.showResult()
    simRptSvr3 = simReport("testcase3", "pass")
    simRptSvr3.showResult()

# > python simReport.py
# Total: 1
# testcase1: pass
# Total: 2
# testcase2: fail
# Total: 3
# testcase3: pass

我们来看看class的组成部分:

当然代码有优化的空间,比如实例对象最好存放到一个python列表里,最终用for ... in ... 结构显示结果。但这不是本文的重点。当然代码有优化的空间,比如实例对象最好存放到一个python列表里,最终用for ... in ... 结构显示结果。但这不是本文的重点。

Tip:
__init__(self, ...)是初始化函数,在instance创建时自动被调用。有些书上也叫“构造函数”,虽然不太准确,但也可以直观地理解。

与C++类的对比

Table python C++
静态变量 方法外部的都是 方法外部,加了static才是
实例变量 定义在方法内部,self.xxx 方法外部,不加static
局部变量 定义在方法内部,不加self 方法内部
实例对象 self,每个方法的第一个参数 this,仅显式引用属性时才需要
访问权限 无,都是public型 private, public, protect,默认是private
构造函数 def __create__(self, ...): classname(...){}
析构函数 def __del__(self): python会自动垃圾回收 ~classname(){} 需要自己处理垃圾回收

关于访问权限,python有一个方法来设置private权限。把属性或者方法定义成__开头(双下划线)。了解一下即可。

总结

今天学习了python的类的定义方法,以及与C++的区别。

习题:
  1. 把文中的simReport.py的代码写一遍,并执行查看结果。
  2. 改进simReport.py把三个对象simRptSvr1、simRptSvr2、simRptSvr3存到列表中,最终用for ... in ... 的方法来打印报告。
阅读数:
更多文章:文章目录
解惑专区
(支持markdown插入源代码)
欢迎使用ExASIC订阅服务
仅用于ExASIC最新文章通知,方便及时阅读。
友情链接: IC技术圈问答ReCclayCrazyFPGA