python 中的嵌套类
在看 idarling 源码中,经常出现如下代码:
import sys
import ida_funcs
import ida_kernwin
from PyQt5.QtCore import ( # noqa: I202
QAbstractItemModel,
QModelIndex,
QObject,
Qt,
)
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QStyledItemDelegate, QWidget
import sip
from .widget import StatusWidget
if sys.version_info > (3,):
long = int
class Painter(QObject):
class ProxyItemDelegate(QStyledItemDelegate):
def __init__(self, delegate, model, parent=None):
super(Painter.ProxyItemDelegate, self).__init__(parent)
self._delegate = delegate
self._model = model
def paint(self, painter, option, index):
index = self._model.index(index.row(), index.column())
self._delegate.paint(painter, option, index)
class ProxyItemModel(QAbstractItemModel):
def __init__(self, model, plugin, parent=None):
super(Painter.ProxyItemModel, self).__init__(parent)
self._model = model
self._plugin = plugin
def index(self, row, column, parent=QModelIndex()):
return self.createIndex(row, column)
def parent(self, index):
index = self._model.index(index.row(), index.column())
return self._model.parent(index)
def rowCount(self): # noqa: N802
return self._model.rowCount()
def columnCount(self): # noqa: N802
return self._model.columnCount()
def data(self, index, role=Qt.DisplayRole):
# Check if disabled by the user
cursors = self._plugin.config["cursors"]
if role == Qt.BackgroundRole and cursors["funcs"]:
func_ea = int(index.sibling(index.row(), 2).data(), 16)
func = ida_funcs.get_func(func_ea)
for user in self._plugin.core.get_users().values():
if ida_funcs.func_contains(func, user["ea"]):
r, g, b = StatusWidget.ida_to_python(user["color"])
return QColor(StatusWidget.Python_to_qt(r, g, b))
index = self._model.index(index.row(), index.column())
return self._model.data(index, role)
def __init__(self, plugin):
super(Painter, self).__init__()
self._plugin = plugin
self._ida_nav_colorizer = None
self._nbytes = 0
def nav_colorizer(self, ea, nbytes):
"""This is the custom nav colorizer used by the painter."""
self._nbytes = nbytes
# There is a bug in IDA: with a huge number of segments, all the navbar
# is colored with the user color. This will be resolved in IDA 7.2.
cursors = self._plugin.config["cursors"]
if cursors["navbar"]:
for user in self._plugin.core.get_users().values():
# Cursor color
if ea - nbytes * 2 <= user["ea"] <= ea + nbytes * 2:
return long(user["color"])
# Cursor borders
if ea - nbytes * 4 <= user["ea"] <= ea + nbytes * 4:
return long(0)
orig = ida_kernwin.call_nav_colorizer(
self._ida_nav_colorizer, ea, nbytes
)
return long(orig)
def ready_to_run(self):
# The default nav colorized can only be recovered once!
ida_nav_colorizer = ida_kernwin.set_nav_colorizer(self.nav_colorizer)
if ida_nav_colorizer is not None:
self._ida_nav_colorizer = ida_nav_colorizer
self.refresh()
def get_ea_hint(self, ea):
cursors = self._plugin.config["cursors"]
if not cursors["navbar"]:
return None
for name, user in self._plugin.core.get_users().items():
start_ea = user["ea"] - self._nbytes * 4
end_ea = user["ea"] + self._nbytes * 4
# Check if the navbar range contains the user's address
if start_ea <= ea <= end_ea:
return str(name)
def get_bg_color(self, ea):
# Check if disabled by the user
cursors = self._plugin.config["cursors"]
if not cursors["disasm"]:
return None
for user in self._plugin.core.get_users().values():
if ea == user["ea"]:
return user["color"]
return None
def widget_visible(self, twidget):
widget = sip.wrapinstance(long(twidget), QWidget)
if widget.windowTitle() != "Functions window":
return
table = widget.layout().itemAt(0).widget()
# Replace the table's item delegate
model = Painter.ProxyItemModel(table.model(), self._plugin, self)
old_deleg = table.itemDelegate()
new_deleg = Painter.ProxyItemDelegate(old_deleg, model, self)
table.setItemDelegate(new_deleg)
def refresh(self):
ida_kernwin.refresh_navband(True)
ida_kernwin.request_refresh(ida_kernwin.IWID_DISASMS)
ida_kernwin.request_refresh(ida_kernwin.IWID_FUNCS)
能够看到 类中 又定义了 类 ,这种情况我们称之为嵌套类 。给一个简单 demo 来认识嵌套类 。
#!/usr/bin/env python
import os, sys
class parent:
def __init__(self):
self.name = 'parent'
def getName(self):
print self.name
class child:
def __init__(self):
self.name = 'child'
def getName(self):
print self.name
if __name__ == '__main__':
child = parent.child()
child.getName()
zhangji16@zhangji16vm:/tmp$ python tmp2.py
child
相关文章