简体   繁体   中英

Python: I can't assign a defined list to the class attribute?

class Runner:
    """
    information of registered runners
    Attributes:
        @type email: str
        email of the registered runner
        @type category: str
        the speed they estimate that they can finish the race
        @type list: clist
        the list of runners in the same category

    """
    under_twenty_min = []
    under_thirty_min = []
    under_forty_min = []
    forty_and_above = []

    def __init__(self, email, category):
        """Register the email and the speed estimation of runners

            @type self: Runner
            @type email: str
            @type speed: int
            @type category:str
            @type clist: list
            @rtype: list

        >>>runner1=Runner('gerhard@mail.utoronto.ca','under 40 min')
        >>>runner1.email
        'gerhard@gmail.utoronto.ca'
        >>>runner1.category
        'under 40 min'
        """
        self.email = email
        self.category = category
        if category=='under 20 min':
            self.clist=under_twenty_min
        elif category=='under 30 min':
            self.clist = under_twenty_min
        elif  category=='under 40 min':
            self.clist = under_forty_min
        elif category=='40 min and over':
            self.clist = forty_and_over
        renew(self,clist)
        return clist

basically i have to return a list of runners with the same speed category when initialize a runner, but I can't assign the lists I defined above to the class attribute, is there anyway to fix it?

You have to explicitly specify the class when accessing class variables:

if category == 'under 20 min':
    self.clist = Runner.under_twenty_min
elif category == 'under 30 min':
    self.clist = Runner.under_twenty_min
elif category == 'under 40 min':
    self.clist = Runner.under_forty_min
elif category == '40 min and over':
    self.clist = Runner.forty_and_over

You can use a dict, set each catgory name as a key and the value is a list of all the runners in that category.
here is a simple implementation

from collections import defaultdict

#runners is a list of all your runners

def get_runners_by_cat():
    d = defaultdict(list)
    for runner in runners:
        dict[runner.category].append(runner)
    return d

There are couple of things you have to modify in your code:

  1. The indentation of the init method needs to be indented within the class definition.
  2. As @Tamas points out you need to explicitly state that the variables are class variable.
  3. As @taoufik mentions, it might be convenient to define a dictionary instead.
  4. A init method should not return anything (except None ). Since your requirement is to return the runners, you could add an additional method as @taofik suggested (or you can just print them once created as shown below).

Here's an updated version of the code. Hope it helps.

class Runner:
    """
    information of registered runners
    Attributes:
        @type email: str
        email of the registered runner
        @type category: str
        the speed they estimate that they can finish the race
        @type list: clist
        the list of runners in the same category

    """
    clist = {
        'under_twenty_min': [],
        'under_thirty_min': [],
        'under_forty_min':[],
        'forty_and_above': []
    }

    def __init__(self, email, category):
        """Register the email and the speed estimation of runners

            @type self: Runner
            @type email: str
            @type speed: int
            @type category:str
                @type clist: list
            @rtype: list

        >>>runner1=Runner('gerhard@mail.utoronto.ca','under 40 min')
        >>>runner1.email
        'gerhard@gmail.utoronto.ca'
            >>>runner1.category
        'under 40 min'
        """
        self.email = email
        self.category = category

        if category=='under 20 min':
            Runner.clist['under_twenty_min'].append(self)
            print Runner.clist['under_twenty_min']
        elif category=='under 30 min':
            Runner.clist['under_thirty_min'].append(self)
            print Runner.clist['under_thirty_min']
        elif  category=='under 40 min':
            Runner.clist['under_forty_min'].append(self)
            print Runner.clist['under_forty_min']
        elif category=='40 min and over':
            Runner.clist['forty_and_above'].append(self)
            print Runner.clist['forty_and_above']
#get class name, convert it to class object
if category=='under 20 min':
    self.clist= eval(self.__class__.__name__).under_twenty_min
elif category=='under 30 min':
    self.clist = eval(self.__class__.__name__).under_thirty_min
elif  category=='under 40 min':
    self.clist = eval(self.__class__.__name__).under_forty_min
elif category=='40 min and over':
    self.clist = eval(self.__class__.__name__).forty_and_above

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM