2014-12-04 100 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'是什麼索引,如果你想在你的化學品清單中找到一種特定的化學品,你將不得不詳細瞭解這些對象。