Using Class, Methods to define variables

两盒软妹~` 提交于 2019-12-13 08:00:51

问题


I have a number of chemicals with corresponding data held within a database, how do I go about returning a specific chemical, and its data, via its formula, eg 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

outputs the following error which I have tried to remedy with no luck; TypeError: 'list' object is not callable


回答1:


Try this function:

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

This function is using the toDict() method found in the Chemical class. The code you pasted from the Chemical class explains that this method returns a dictionary from the chemical object:

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

This dictionary looks like this:

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

What the function I created above does is iterate through all of the chemicals in the list, finds the first one with a name equal to "o2", and returns that chemical. Here's how to use it:

chemByString("o2",allChemicals).chemicalName

If the above does not work, may want to try using the alternative priority ("tv"), though I'm unsure if this will have any effect:

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

If the chemical isn't found, the function returns None:

chemByString("myPretendChemical",allChemicals).chemicalName



回答2:


The issue is the two lines

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

allChemical is a list, and you can't just do a_list(). It looks like you're trying to find either ['o2'] or just 'o2' in a list. To do that, you can get the index of the item and then get that index from the list.

allChemical[allChemical.index("o2")]



回答3:


EDIT: See my new answer. Leaving this one here since it might still be helpful info.

In python, a list object is a structure holding other objects with an index for each object it contains. Like this:

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

If you want to get to one of those objects, you have to know its index:

objList[0] #returns "hello" string object

If you don't know the index, you can find it using the index method:

objList.index("hello") #returns 0

Then you can get the object out of the list using the found index:

objList[objList.index("hello")]

However this is kind of silly, since you can just do:

"hello"

Which in this case will produce the same result.

Your allChemical object is a list. It looks like the line chemicalFiles = ("/home/temp.txt") is filling your list with some type of object. In order to answer your question, you have to provide more information about the objects which the list contains. I assume that information is in the ParseClasses module you are using.

If you can provide more information about the Chemical object you are importing, that may go a long way to helping solve your problem.

IF the objects contained in your list are subclassed from str, this MAY work:

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

"02" is a str object, so index is going to look for a str object (or an object subclassed from str) in your list to find its index. However, if the object isn't a string, it will not find it.

As a learning exercise, try this:

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

This works because index is able to find what you are looking for. If it isn't a string it can't find it, and if you don't know what index 'o2' is at, if you want to get to a specific chemical in your list of chemicals you're going to have to learn more about those objects.



来源:https://stackoverflow.com/questions/27298709/using-class-methods-to-define-variables

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!