我有一个课程,我借助各种方法收集数据(比如说23)。每个方法都使用list并可以修改它。我的问题是如何以更普遍接受的方式调用(在课堂上)所有类的方法?
class Example(object):
def __init__(self):
self.lst = []
def multiply(self):
for i in xrange(10):
self.lst.append(i**2)
def get_list(self):
return self.lst
# Calling:
ex = Example()
ex.multiply
print ex.get_list
# What I want is call multiply method inside class and just do this
print ex.get_list
示例类说明了我的想法。我知道可以通过使用Example .__ dict__values()迭代来解决我的问题,在一个类的方法或者使用inspect模块调用所有方法,但我不确定没有更多纯粹的Pythonic方法。
更新
我想要的只是收集yapf格式化程序的配置数据。
主要问题是如何调用类中的所有方法 - 我不想在一个方法中实现输入文件的所有配置分析。 OOP和模式是我的指南。
更新2: 回答Jared Goguen。我想创建类来收集数据到字典并将其发送到CreateStyleFromConfig方法。 当它完成后,我只想从类中获取get_style方法而不调用其中的所有方法:
config = ConfData() # Class which collects all configurations from file
config.get_style()
ConfData类包含特定于数据名称的方法。例如:
def align_closing_bracket_with_visual_indent(self):
# Do some work..
pass
答案 0 :(得分:0)
所以,我想有两个可能的解决方案,但我不喜欢其中任何一个。我想你可能会以错误的方式解决这个问题。
您可以使用外部装饰器track
和类变量tracker
来跟踪您要调用的方法。
def track(tracker):
def wrapper(func):
tracker.append(func)
return func
return wrapper
class Example:
tracker = []
@track(tracker)
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
@track(tracker)
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
def collect_data(self):
return dict(tup for method in self.tracker for tup in method(self))
print Example().collect_data()
# {'key_b1': 'val_b1', 'key_b2': 'val_b2', 'key_a1': 'val_a1', 'key_a2': 'val_a2'}
通过这种方法,您可以在课堂上使用您不想打电话的实用方法。
另一种方法是检查类的目录,并在逻辑上确定要调用的方法。
from inspect import ismethod
class Example:
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
def collect_data(self):
data = {}
for attr in dir(self):
if not attr.startswith('_') and attr != 'collect_data':
possible_method = getattr(self, attr)
if ismethod(possible_method):
data.update(possible_method())
return data
此方法类似于帖子中提到的方法(即迭代__dict__
)并且很弱,因为您不想要调用的任何实例方法都需要从' _'开始。您可以调整此方法以使用其他任何命名约定,但其他人可能无法读取。
这些方法中的任何一个都可以将collect_data
部分实现为超类,允许您创建最小的子类。对第一种方法来说,这并没有多大帮助。
class MethodTracker(object):
def collect_data(self):
return dict(tup for method in self.tracker for tup in method(self))
class Example(MethodTracker):
tracker = []
@track(tracker)
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
@track(tracker)
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]
使用第二种方法,得到的子类是最小的。此外,你可以做一些反思,让超级班级有实用的方法,不要以' _'
开头。from inspect import ismethod
class MethodTracker(object):
def collect_data(self):
data = {}
for attr in dir(self):
if not attr.startswith('_') and not hasattr(MethodTracker, attr):
possible_method = getattr(self, attr)
if ismethod(possible_method):
data.update(possible_method())
return data
def decoy_method(self):
return 'This is not added to data.'
class Example(MethodTracker):
def method_a(self):
return [('key_a1', 'val_a1'), ('key_a2', 'val_a2')]
def method_b(self):
return [('key_b1', 'val_b1'), ('key_b2', 'val_b2')]