class libAddress(tfLibClass):
"""
@class libAddress
@brief Pack some common APIs for Pba/Lba
"""
def __init__(self, testcase):
"""
@fn __init__
@brief Initialization of the commands class. Sets class instance variables.
@retval This method returns no values.
@exception This method raises no exceptions.
"""
super(libAddress, self).__init__(testcase)
self.storPhyInfo = self.testcase.vs.getStoragePhyInfo()
self.rgPageCntPerRgBlk = self.storPhyInfo.numPagesInBlock
def _getPbaStr(self):
class pbaStr(ctypes.LittleEndianStructure):
_fields_ = [
("unit", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfUnit),
("die", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfDie),
("rgRow", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRgRow),
("rg", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRg),
#no revd bit("rsvd", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRsvd),
#RgBlk & RgPage add here only for parsing RgRow,not normal Pba struct
# ("rgPage", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRgPage),
# ("rgBlk", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRgBlk),
]
@property
def rgPage(self):
return self.rgPage
@rgPage.setter
def rgPage(self, rgPageVal):
rgBlkOldVal = self.rgRow // self.rgPageCntPerRgBlk
rgRawVal = rgBlkOldVal * self.rgPageCntPerRgBlk + rgPageVal
self.rgRow = rgRawVal
return type('PBAStrCls', (pbaStr,), {})
直接调用self.rgPageCntPerRgBlk 会报AttributeError: 'PBAStrCls' object has no attribute 'rgPageCntPerRgBlk',如何在以上rgPage的函数中调用self.rgPageCntPerRgBlk
基于new Bing的编写:
在您提供的代码中,rgPage属性的setter方法试图访问self.rgPageCntPerRgBlk,但是这个属性是定义在libAddress类中的,而不是在内部类pbaStr中。由于pbaStr类没有定义rgPageCntPerRgBlk属性,所以会报错。
您可以通过将libAddress类的实例作为参数传递给pbaStr类来解决此问题。例如,在_getPbaStr方法中,您可以将当前实例(即self)作为参数传递给pbaStr类:
def _getPbaStr(self):
class pbaStr(ctypes.LittleEndianStructure):
def __init__(self, lib_address):
self.lib_address = lib_address
...
...
@rgPage.setter
def rgPage(self, rgPageVal):
rgBlkOldVal = self.rgRow // self.lib_address.rgPageCntPerRgBlk
...
然后,在创建pbaStr类的实例时,您可以将当前实例(即self)作为参数传递:
pba_str = pbaStr(self)
这样,在pbaStr类中,您就可以通过访问self.lib_address.rgPageCntPerRgBlk来访问外层类中的变量了。
修改过后:
class libAddress(tfLibClass):
"""
@class libAddress
@brief Pack some common APIs for Pba/Lba
"""
def __init__(self, testcase):
"""
@fn __init__
@brief Initialization of the commands class. Sets class instance variables.
@retval This method returns no values.
@exception This method raises no exceptions.
"""
super(libAddress, self).__init__(testcase)
self.storPhyInfo = self.testcase.vs.getStoragePhyInfo()
self.rgPageCntPerRgBlk = self.storPhyInfo.numPagesInBlock
def _getPbaStr(self):
class pbaStr(ctypes.LittleEndianStructure):
# 添加一个初始化方法,接收外层类的实例作为参数
def __init__(self, lib_address):
self.lib_address = lib_address
_fields_ = [
("unit", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfUnit),
("die", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfDie),
("rgRow", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRgRow),
("rg", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRg),
#no revd bit("rsvd", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRsvd),
#RgBlk & RgPage add here only for parsing RgRow,not normal Pba struct
# ("rgPage", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRgPage),
# ("rgBlk", ctypes.c_uint32, self.cfgAddr.pbaBitsCountOfRgBlk),
]
@property
def rgPage(self):
return self.rgPage
@rgPage.setter
def rgPage(self, rgPageVal):
# 通过访问self.lib_address.rgPageCntPerRgBlk来访问外层类中的变量
rgBlkOldVal = self.rgRow // self.lib_address.rgPageCntPerRgBlk
rgRawVal = rgBlkOldVal * self.lib_address.rgPageCntPerRgBlk + rgPageVal
self.rgRow = rgRawVal
# 在创建pbaStr类的实例时,将当前实例(即self)作为参数传递
pba_str = pbaStr(self)
不知道你这个问题是否已经解决, 如果还没有解决的话:解决方案: 在装饰器内调用外层class中的变量需要使用外层class的实例化对象来访问变量。
具体步骤如下:
class PBAStrCls:
def __init__(self):
self.rgPageCntPerRgBlk = 10
class PBAStrCls:
def __init__(self):
self.rgPageCntPerRgBlk = 10
class InnerClass:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
# 通过self.func.__name__可以获取到被装饰函数的名字
print(f"调用函数:{self.func.__name__}之前,self.rgPageCntPerRgBlk:{args[0].rgPageCntPerRgBlk}")
result = self.func(*args, **kwargs)
print(f"调用函数:{self.func.__name__}之后")
return result
class PBAStrCls:
def __init__(self):
self.rgPageCntPerRgBlk = 10
class InnerClass:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f"调用函数:{self.func.__name__}之前,self.rgPageCntPerRgBlk:{args[0].rgPageCntPerRgBlk}")
result = self.func(*args, **kwargs)
print(f"调用函数:{self.func.__name__}之后")
return result
@InnerClass
def test(self):
print("装饰的函数test被调用了")
pba = PBAStrCls()
pba.test()
输出结果将会是:
调用函数:test之前,self.rgPageCntPerRgBlk:10
装饰的函数test被调用了
调用函数:test之后