尝试确定我是否应该尝试使用装饰器或其他一些Pythonic方法来减少我的许多函数正在执行的代码。我希望这些函数能够在每个函数的开头调用可能的另一个函数,或以某种方式“装饰”每个函数的开头。我之前从未使用过装饰器,并且正在努力以pythonic方式实现这种装饰思想,以减少每个函数的共同代码集。
我有很多函数会在函数开始时执行相同的一组步骤。但是,公共代码存在一些结构问题,使得这个“装饰者”的想法变得困难:
这些函数都在父类的子类中。
函数之间的通用命令引用变量名称 特定于函数的函数(但函数的子集 名称)。
常用命令需要返回调用者而不执行任何操作 如果满足某个条件,则更多的子功能。 (“if jobj:”示例代码中的块)
对于变量/属性示例,子函数get_nas_server(self)将在公共代码集中使用“nas_server”变量变量。从函数名中减去get_会显示要在公共代码集中使用的变量名的基础。从“get_nas_server”函数名称派生的示例变量名称和对象属性:
nas_server
nas_server.json
self.nas_server(属性)
以下是其中一个功能的公共代码:
####################################################################
def get_nas_server(self):
####################################################################
"""\nGets COMMAND nas_server and places data into self.nas_server"""
try:
self.nas_server
return self.nas_server
except AttributeError:
pass
self.get_file_cmd('nas_server')
jobj = self.fresh_json('nas_server.json')
if jobj :
self.nas_server = jobj
return self.nas_server
self.get_file_cmd('get_nas_server')
函数中上面代码下面的所有内容都是特定于功能目的,不适合在此讨论。基本上我试图在我的函数中重复使用上面的所有代码,但代码必须根据函数名称更改变量和属性。
感谢您阅读,如果您有这么远,感谢您的帮助。
答案 0 :(得分:2)
似乎你可以在父类中定义为辅助方法:
class Parent(object):
def _get_something(name):
try:
return getattr(self, name)
except AttributeError:
pass
self.get_file_cmd(name)
jobj = self.fresh_json(name+'.json')
if jobj :
setattr(self, name, jobj)
return jobj
self.get_file_cmd('get_'+name)
答案 1 :(得分:1)
如果初始簿记内容对于该类太具体,您可以在课堂内使用装饰器。每次你需要在类方法中进行初始检查时,你可以使用我在下面添加的auto_nas
装饰器来装饰它。我假设,这个包装器的范围仅针对这个类。否则,您可以将其移到课堂之外以获得一般性,但如果您打算这样做,请记得更改(self=None)
。
class YourMainClass():
# This is your main class inside which all the methods are defined.
def auto_nas(func):
# This wrapper function will be called instead of your class methods.
def wrap(self):
# All your bookkeeping stuff goes here.
try:
self.nas_server
return self.nas_server
except AttributeError:
pass
self.get_file_cmd('nas_server')
jobj = self.fresh_json('nas_server.json')
if jobj :
self.nas_server = jobj
return self.nas_server
self.get_file_cmd('get_nas_server')
# Things went well - we shall call the actual method.
return func(self)
return wrap
@auto_nas
def get_nas_server(self):
# This is one of your methods that require bookkeeping
pass
另外,请注意包装函数中的self
。它由Python自动作为参数传递,因此您可以从该装饰器内部访问所有特定于实例的属性。再一次,如果您的装饰者必须针对您班级的每个实例执行特定工作,这是合适的。如果不是这样,你可以简单地将所有代码放在一个函数中,并在每次需要时调用它。
答案 2 :(得分:0)
非常感谢Augurar指出正确的方向。我最终在父类中创建了一个存根方法。只需要用适当的技术调用该方法来“扩展”父方法。然后使用super()从子类调用该stub方法这个技术必须有一个合适的名称?方法覆盖?方法扩展?
这是父类方法,主要是因为Augurar建议:
###########################################################################
def get_stub(self,fcmd):
###########################################################################
try:
return getattr(self, fcmd)
except AttributeError:
pass
jobj = self.fresh_json(fcmd + '.json')
if jobj :
setattr(self, fcmd, jobj)
return jobj
if not self.get_file_cmd(fcmd):
self.log.error("{} not found".format(fcmd))
return False
以下是子方法使用此父方法的方式:
####################################################################
def get_nas_server(self):
####################################################################
super().get_stub('nas_server')
#bunch of child method specific code below here