2014-12-04 53 views
-1

我有很多与数据库中保存相应的数据,我怎么去返回一个特定的化学,其数据的化学品,通过其配方,如O2。使用类,方法来定义变量

class SourceNotDefinedException(Exception): 
def __init__(self, message): 
    super(SourceNotDefinedException, self).__init__(message) 

class tvorechoObject(object): 
"""The class stores a pair of objects, "tv" objects, and "echo" objects. They are accessed 
simply by doing .tv, or .echo. If it does not exist, it will fall back to the other variable. 
If neither are present, it returns None.""" 
def __init__(self, echo=None, tv=None): 
    self.tv = tv 
    self.echo = echo 

def __repr__(self): 
    return str({"echo": self.echo, "tv": self.tv}) # Returns the respective strings 

def __getattribute__(self, item): 
    """Altered __getattribute__() function to return the alternative of .echo/.tv if the requested 
    attribute is None.""" 

    if item in ["echo", "tv"]:  
     if object.__getattribute__(self,"echo") is None: # Echo data not present 
      return object.__getattribute__(self,"tv") # Select TV data 
     elif object.__getattribute__(self,"tv") is None: # TV data not present 
      return object.__getattribute__(self,"echo") # Select Echo data 
     else: 
      return object.__getattribute__(self,item) # Return all data 

    else: 
     return object.__getattribute__(self,item) # Return all data 


class Chemical(object): 
    def __init__(self, inputLine, sourceType=None): 
     self.chemicalName = TVorEchoObject()  
     self.mass = TVorEchoObject() 
     self.charge = TVorEchoObject() 


     self.readIn(inputLine, sourceType=sourceType) 

def readIn(self, inputLine, sourceType=None): 

    if sourceType.lower() == "echo": # Parsed chemical line for Echo format 


     chemicalName   = inputLine.split(":")[0].strip() 
     mass    = inputLine.split(":")[1].split(";")[0].strip() 
     charge     = inputLine.split(";")[1].split("]")[0].strip() 


     # Store the objects 
     self.chemicalName.echo = chemicalName 
     self.mass.echo = mass 
     self.charge.echo = charge 


    elif sourceType.lower() == "tv": # Parsed chemical line for TV format 


     chemicalName   = inputLine.split(":")[0].strip() 
     charge    = inputLine.split(":")[1].split(";")[0].strip() 
     mass     = inputLine.split(";")[1].split("&")[0].strip() 


     # Store the objects 
     self.chemicalName.tv = chemicalName 
     self.charge.tv = charge 
     self.mass.tv = molecularWeight 

    else: 
     raise SourceNotDefinedException(sourceType + " is not a valid `sourceType`") # Otherwise print 


def toDict(self, priority="echo"): 
    """Returns a dictionary of all the variables, in the form {"mass":<>, "charge":<>, ...}. 
    Design used is to be passed into the Echo and TV style line format statements.""" 
    if priority in ["echo", "tv"]: 
    # Creating the dictionary by a large, to avoid repeated text 
     return dict([(attributeName, self.__getattribute__(attributeName).__getattribute__(priority)) 
      for attributeName in ["chemicalName", "mass", "charge"]]) 
    else: 
     raise SourceNotDefinedException("{0} source type not recognised.".format(priority)) # Otherwise print 






from ParseClasses import Chemical 
allChemical = [] 
chemicalFiles = ("/home/temp.txt") 


for fileName in chemicalFiles: 
    with open(fileName) as sourceFile: 
     for line in sourceFile: 
     allChemical.append(Chemical(line, sourceType=sourceType)) 

for chemical in allChemical: 
    print chemical.chemicalName #Prints all chemicals and their data in list format 

for chemical in allChemical(["o2"]): 
    print chemical.chemicalName 

输出下面的错误,我试图补救没有运气; 类型错误:“名单”对象不是可调用

+0

貌似'allChemicals'是一个'list' - 你的意思是'化学在allChemicals [2]:'甚至'为所有化学制品中的化学物质:'?你需要给我们更多关于你的数据结构的细节,否则我们只能猜测。另请参阅本文有关如何编写[最小,完整和可验证示例](http://stackoverflow.com/help/mcve)。 – 2014-12-04 16:15:53

+0

它看起来像'allChemicals'应该是某种物体的列表。你需要在这里包含它的定义和对象定义,以便我们能够告诉你如何使用它们。 – khelwood 2014-12-04 16:21:29

+0

“allChemicals”是否是错字?如果是这样,当你这样做:'allChemical = []'你正在制作一个名为allChemical的空列表。然后当你这样做时:'allChemicals([“o2”])'你正在调用列表(这就是括号里的内容)和一个参数。你不能以这种方式调用列表对象。你没有正确使用'allChemical'对象。这是导致错误的原因。很难说如何在没有更多信息的情况下修复它。 – 2014-12-04 16:32:55

回答

1

试试这个功能:

def chemByString(chemName,chemicals,priority="echo"): 
    for chemical in chemicals: 
     chemDict = chemical.toDict(priority) 
     if chemDict["chemicalName"] == chemName 
      return chemical 
    return None 

此功能使用在Chemical类中找到的toDict()方法。你从Chemical类粘贴代码解释说,这种方法从化学对象返回的字典:

def toDict(self, priority="echo"): 
    """Returns a dictionary of all the variables, in the form {"mass":<>, "charge":<>, ...}. 
    Design used is to be passed into the Echo and TV style line format statements.""" 
    if priority in ["echo", "tv"]: 
    # Creating the dictionary by a large, to avoid repeated text 
     return dict([(attributeName, self.__getattribute__(attributeName).__getattribute__(priority)) 
      for attributeName in ["chemicalName", "mass", "charge"]]) 
    else: 
     raise SourceNotDefinedException("{0} source type not recognised.".format(priority)) # Otherwise print 

这本词典是这样的:

"chemicalName" : <the chemical name> 
"mass" :   <the mass> 
"charge" :  <the charge> 

我在上面创建的功能确实是遍历列表中的所有化学品都会找到名称等于“o2”的第一个化合物,然后返回该化学品。以下是如何使用它:

chemByString("o2",allChemicals).chemicalName 

如果上述方法无效,可能要使用替代优先级(“TV”)的尝试,虽然我不能确定这是否会产生什么影响:

chemByString("o2",allChemicals,"tv").chemicalName 

如果没有找到化学,函数返回None

chemByString("myPretendChemical",allChemicals).chemicalName 
+0

非常感谢你。这非常有帮助,我仍然有问题返回与O2的所有数据有关的所有字典对象,即质量和电荷。 – 2014-12-11 11:24:13

+0

虽然优先级被定义,但代码仍然输出来自echo和tv的数据? – 2014-12-11 11:45:50

+0

嗯...是的,我不确定这是如何工作的。代码有点令人困惑,我还没有试图自己运行它。我会尽量在有空的时候记得再看一遍。如果您仍然有问题,请在一两天内提醒我。 – 2014-12-11 13:30:35

2

的问题是两线

for chemical in allChemical(["o2"]): 
    print chemical.chemicalName 

allChemical是一个列表,你不能只是做a_list()。看起来您正在尝试在列表中找到['o2']或只是'o2'。为此,您可以获取该项目的索引,然后从列表中获取该索引。

allChemical[allChemical.index("o2")] 
+1

虽然这个问题比这个更大。 'list'中的对象似乎不是字符串,所以'index(“o2”)'可能找不到它们。除非它们从'str'或类似的东西被分类。 – 2014-12-04 16:58:00

+0

@RickTeachey这是一个好点... – TankorSmash 2014-12-04 17:00:42

1

编辑:看到我的新答案。因为它可能仍然是有用的信息,所以留在这里。

在Python中,一个列表对象是保持其他的目的与索引为每个对象包含的结构。就像这样:

Index Object 
0  "hello" 
1  "world" 
2  "spam" 

如果你想获得这些对象之一,你必须知道它的索引:

objList[0] #returns "hello" string object 

如果你不知道索引,你可以用它找到index方法:

objList.index("hello") #returns 0 

然后你就可以使用创建索引获取对象淘汰之列

然而,这是一种愚蠢的,因为你可以这样做:

"hello" 

在这种情况下会产生相同的结果。

allChemical对象的列表。它看起来像行chemicalFiles = ("/home/temp.txt")正在填充您的列表与某种类型的对象。为了回答您的问题,您必须提供有关列表中包含的对象的更多信息。我假设这些信息位于您正在使用的ParseClasses模块中。

如果你能提供有关Chemical对象要导入,可能很长的路要走,以帮助您解决问题的详细信息。

如果包含在列表中的对象从str子类,这可能工作:

allChemical[allChemical.index("o2")].chemicalName 

"02"str对象,所以index是要寻找一个str对象(或物体str子类)在你的列表中找到它的索引。但是,如果对象不是字符串,它将不会找到它。

作为一个学习锻炼,试试这个:

class Chemical(str): 
'''A class which is a subclass of string but has additional attributes such as chemicalName''' 
    def __init__(self,chemicalName): 
     self.chemicalName = chemicalName 

someChemicals = [Chemical('o2'),Chemical('n2'),Chemical('h2')] 

for chemical in someChemicals: print(chemical.chemicalName) 
#prints all the chemical names 
print(someChemicals[0].chemicalName) 
#prints "o2"; notice you have to know the index ahead of time 
print(someChemicals[someChemicals.index("o2")].chemicalName) 
#prints "o2" again; this time index found it for you, but 
#you already knew the object ahead of time anyway, sot it's a little silly 

这工作,因为指数是能够找到你在找什么。如果它不是一个字符串,它不能找到它,如果你不知道'o2'是什么索引,如果你想在你的化学品清单中找到一种特定的化学品,你将不得不详细了解这些对象。