我有一个项目,我通过"cleans"
个特定函数运行多个数据。
清洁功能如下: Misc.py
def clean(my_data)
sys.stdout.write("Cleaning genes...\n")
synonyms = FileIO("raw_data/input_data", 3, header=False).openSynonyms()
clean_genes = {}
for g in data:
if g in synonyms:
# Found a data point which appears in the synonym list.
#print synonyms[g]
for synonym in synonyms[g]:
if synonym in data:
del data[synonym]
clean_data[g] = synonym
sys.stdout.write("\t%s is also known as %s\n" % (g, clean_data[g]))
return data
FileIO
是我打开文件的自定义类。
我的问题是,在整个程序的生命周期中会多次调用此函数。我想要实现的是不必每次都读取input_data,因为它每次都是相同的。我知道我可以回复它,并以这种方式将其作为参数传递:
def clean(my_data, synonyms = None)
if synonyms == None:
...
else
...
但还有另一种更好看的方式吗?
我的文件结构如下:
lib
Misc.py
FileIO.py
__init__.py
...
raw_data
runme.py
从runme.py
,我执行此操作from lib import *
并调用我所做的所有功能。
有没有一种pythonic方式来解决这个问题?就像一个记忆'用于功能
编辑:
这一行:synonyms = FileIO("raw_data/input_data", 3, header=False).openSynonyms()
从collections.OrderedDict()
返回input_data
,并使用第3列作为字典的键。
以下数据集的字典:
column1 column2 key data
... ... A B|E|Z
... ... B F|W
... ... C G|P
...
看起来像这样:
OrderedDict([('A',['B','E','Z']), ('B',['F','W']), ('C',['G','P'])])
这告诉我的脚本A
也称为B,E,Z
。 B
为F,W
。等...
所以这些是同义词。因为,同义词列表在代码的整个生命周期中永远不会改变。我想只阅读一次,然后重复使用它。
答案 0 :(得分:4)
使用带__call__运算符的类。您可以调用此类的对象,并在对象中的调用之间存储数据。一些数据可能最好由构造函数保存。你用这种方式制作的被称为“仿函数”或“可调用对象”。
示例:
class Incrementer:
def __init__ (self, increment):
self.increment = increment
def __call__ (self, number):
return self.increment + number
incrementerBy1 = Incrementer (1)
incrementerBy2 = Incrementer (2)
print (incrementerBy1 (3))
print (incrementerBy2 (3))
输出:
4
5
[编辑]
请注意,您可以将@Tagc的答案与我的答案结合起来,以创建您正在寻找的内容:具有内置内存的“功能”。
为您的班级Clean
而非DataCleaner
命名,并为实例clean
命名。将方法命名为__call__
而不是clean
。
答案 1 :(得分:3)
就像函数的“记忆”一样
重新发现面向对象编程的一半。
将数据清理逻辑封装在类中,例如DataCleaner
。使其成为实例在实例化时读取同义词数据,然后将该信息作为其状态的一部分保留。让该类公开一个对数据进行操作的clean
方法:
class FileIO(object):
def __init__(self, file_path, some_num, header):
pass
def openSynonyms(self):
return []
class DataCleaner(object):
def __init__(self, synonym_file):
self.synonyms = FileIO(synonym_file, 3, header=False).openSynonyms()
def clean(self, data):
for g in data:
if g in self.synonyms:
# ...
pass
if __name__ == '__main__':
dataCleaner = DataCleaner('raw_data/input_file')
dataCleaner.clean('some data here')
dataCleaner.clean('some more data here')
作为未来可能的优化,您可以扩展此方法以使用factory method创建DataCleaner
的实例,这些实例可以根据提供的同义词文件缓存实例(因此您不需要每次为同一个文件做昂贵的重新计算。)
答案 2 :(得分:1)
我认为最简洁的方法是装饰你的" clean
" (双关语)函数与另一个为函数提供synonyms
局部函数的函数。这是iamo更干净,比创建另一个自定义类更简洁,但仍然允许您轻松更改" input_data"文件,如果你需要(工厂功能):
def defineSynonyms(datafile):
def wrap(func):
def wrapped(*args, **kwargs):
kwargs['synonyms'] = FileIO(datafile, 3, header=False).openSynonyms()
return func(*args, **kwargs)
return wrapped
return wrap
@defineSynonyms("raw_data/input_data")
def clean(my_data, synonyms={}):
# do stuff with synonyms and my_data...
pass