我们知道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类的语法即可,找出与其它语言的差异。
我们直接上一个例子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创建时自动被调用。有些书上也叫“构造函数”,虽然不太准确,但也可以直观地理解。
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++的区别。