我有一系列用于对数据进行分类的功能。每个函数都传递相同的输入。该系统的目标是能够随意放入新的分类功能,而无需进行任何调整。
为此,我使用了从here取消的classes_in_module
函数。然后,将在每个输入上运行一个python文件中的每个分类器。
但是,我发现将分类器实现为类或函数是kludgy。类意味着实例化和执行,而函数缺乏干净的内省,允许我查询名称或使用继承来定义公共值。
这是一个例子。首先,类实现:
class AbstractClassifier(object):
@property
def name(self):
return self.__class__.__name__
class ClassifierA(AbstractClassifier):
def __init__(self, data):
self.data = data
def run(self):
return 1
这可以以这种方式使用,假设classifier_list
是包含classes_in_module
的文件中ClassifierA
的输出:
result = []
for classifier in classifier_list:
c = classifier(data)
result.append(c.run())
然而,这似乎有点傻。这个类显然是静态的,并不真正需要维护自己的状态,因为它被使用一次并被丢弃。分类器实际上是一个函数,但后来我失去了共享name
属性的能力 - 我将不得不使用丑陋的内省技术sys._getframe().f_code.co_name
并为每个分类器函数复制该代码。分类器之间的任何其他共享属性也将丢失。
答案 0 :(得分:2)
函数可以包含成员数据。您还可以使用func_name
属性找到函数的名称。
def classifier(data):
return 1
classifier.name = classifier.func_name
print(classifier.name) #classifier
如果您希望多个函数的行为方式相同,则可以使用装饰器。
function_tracker = []
def add_attributes(function):
function.name = function.func_name
function.id = len(function_tracker)
function_tracker.append(function)
return function
@add_attributes
def classifier(data):
return 1
print(classifier.name, classifier.id) # 'classifier', 0
这会在特定情况下避免上课吗?
答案 1 :(得分:1)
如果您不需要该类的多个实例(而且似乎没有),请创建该类的一个实例并将run
更改为__call__
:
class AbstractClassifier(object):
@property
def name(self):
return self.__class__.__name__
class ClassifierA(AbstractClassifier):
def __call__(self, data):
return 1
ClassifierA = ClassifierA() # see below for alternatives
然后在你的其他代码中:
result = []
for classifier in classifier_list:
result.append(classifier(data))
不是让ClassifierA = ClassifierA()
(不是很优雅),而是可以做到:
classifier_list = [c() for c in (ClassifierA, ClassifierB, ...)]
如果您需要创建更多的实例,此方法可以让您的类保持方便;如果你不需要有多个实例,你可以使用装饰器来IAYG(实例化你去;):
def instantiate(cls):
return cls()
@instantiate
class ClassifierZ(object):
def __call__(self, data):
return some_classification
答案 2 :(得分:1)
将类实例用作函数:
class ClassifierA(AbstractClassifier):
def __init__(self, data):
self.data = data
def __call__(self):
return 1
result = []
for classifier in classifier_list:
c = classifier(data)
result.append(c())
或者只是使用功能:
classifier_list = []
def my_decorator(func):
classifier_list.append(func)
return func
@my_decorator
def classifier_a(data):
return 1
result = []
for classifier in classifier_list:
c = classifier(data)
result.append(c)