【问题标题】:Python: I can't assign a defined list to the class attribute?Python:我不能将定义的列表分配给类属性?
【发布时间】:2017-01-16 14:47:53
【问题描述】:
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

基本上我在初始化跑步者时必须返回一个具有相同速度类别的跑步者列表,但是我无法将上面定义的列表分配给类属性,有没有办法修复它?

【问题讨论】:

标签: python computer-science


【解决方案1】:

访问类变量时必须显式指定类:

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

【讨论】:

  • 您也可以使用self.__class__ 和/或@classproperty 来获得更动态的行为
【解决方案2】:

您可以使用字典,将每个类别名称设置为键,值是该类别中所有跑步者的列表。
这是一个简单的实现

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

【讨论】:

    【解决方案3】:

    您必须在代码中修改几件事:

    1. init 方法的缩进需要在类定义中缩进。
    2. 正如@Tamas 指出的那样,您需要明确声明变量是类变量。
    3. 正如@taoufik 所提到的,改为定义字典可能更方便。
    4. init 方法不应返回任何内容(None 除外)。由于您的要求是返回跑步者,您可以按照@taofik 的建议添加一个额外的方法(或者您可以在创建后打印它们,如下所示)。

    这是代码的更新版本。希望对您有所帮助。

    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']
    

    【讨论】:

      【解决方案4】:
      #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
      

      【讨论】:

        猜你喜欢
        • 2021-12-02
        • 2019-11-24
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        • 2021-12-14
        • 2015-07-16
        • 2021-06-22
        • 2013-02-22
        相关资源
        最近更新 更多