方法__init__参数太多

时间:2019-04-01 01:40:40

标签: python

我是Python的超级新手(大约三周前开始),我正在尝试制作一个脚本,该脚本可抓取网页以获取信息。检索到信息后,它将通过函数对其进行格式化,然后将其传递给以17个变量为参数的类。该类使用此信息来计算其他一些变量,并且当前具有构造字典的方法。代码按预期工作,但是我在Pycharm上使用的名为SonarLint的插件强调了17个变量太多而不能用作参数?

我一直在寻找将信息传递给类的替代方法,例如在元组或列表中,但是找不到很多看起来相关的信息。将许多变量作为参数传递给类的最佳实践是什么?还是我根本不应该在此类中使用类?

为了便于阅读,我减少了变量和代码的数量,但这是类;

Class GenericEvent:

    def __init__(self, type, date_scraped, date_of_event, time, link, 
                 blurb):

      countdown_delta = date_of_event - date_scraped
      countdown = countdown_delta.days

      if countdown < 0:
          has_passed = True
      else:
          has_passed = False

      self.type = type
      self.date_scraped = date_scraped
      self.date_of_event = date_of_event
      self.time = time
      self.link = link
      self.countdown = countdown
      self.has_passed = has_passed
      self.blurb = blurb

    def get_dictionary(self):

      event_dict = {}
      event_dict['type'] = self.type
      event_dict['scraped'] = self.date_scraped
      event_dict['date'] = self.date_of_event
      event_dict['time'] = self.time
      event_dict['url'] = self.link
      event_dict['countdown'] = self.countdown
      event_dict['blurb'] = self.blurb
      event_dict['has_passed'] = self.has_passed

      return event_dict

按照以下方式清理数据后,我一直将变量作为key:value对传递给该类:

event_info = GenericEvent(type="Lunar"
                          date_scraped=30/01/19
                          date_of_event=28/07/19
                          time=12:00
                          link="www.someurl.com"
                          blurb="Some string.")

并通过调用以下方法检索字典:

event_info.get_dictionary()

我打算在类中添加其他方法以执行其他操作(不仅仅是创建1个字典),但想在扩展类的功能之前解决此问题。

任何帮助或链接将不胜感激!

2 个答案:

答案 0 :(得分:2)

一个选项是命名元组:

from typing import Any, NamedTuple


class GenericEvent(NamedTuple):
    type: Any
    date_scraped: Any
    date_of_event: Any
    time: Any
    link: str
    countdown: Any
    blurb: str

    @property
    def countdown(self):
        countdown_delta = date_of_event - date_scraped
        return countdown_delta.days

    @property
    def has_passed(self):
        return self.countdown < 0

    def get_dictionary(self):
        return {
            **self._asdict(),
            'countdown': self.countdown,
            'has_passed': self.has_passed,
        }

(将Any替换为字段的实际类型,例如datetime.datetime。)

或者,如果您希望它是可变的,请使用data class

答案 1 :(得分:0)

我认为您的操作没有任何问题。但是,您可以将参数作为一个单独的dict对象,然后通过遍历该dict或对每个dict进行明确的操作来处理它们。就您而言,这似乎会使您的代码更混乱。

由于构造函数的所有参数都是命名参数,因此您可以执行以下操作:

def __init__(self, **params):

这将为您提供一个名为 params 的字典,您可以随后对其进行处理。键是您的参数名称,值是参数值。

如果将参数名与键要在 get_dictionary 方法的返回值中对齐的参数对齐,则将该参数作为一个整体保存起来会使该方法编写起来很简单。

以下是您的代码的缩写版本(已修复一些语法错误),它说明了这一思想:

from pprint import pprint

class GenericEvent:

    def __init__(self, **params):
        pprint(params)

event_info = GenericEvent(type="Lunar",
                          date_scraped="30/01/19",
                          date_of_event="28/07/19",
                          time="12:00",
                          link="www.someurl.com",
                          blurb="Some string.")

结果:

{'blurb': 'Some string.',
 'date_of_event': '28/07/19',
 'date_scraped': '30/01/19',
 'link': 'www.someurl.com',
 'time': '12:00',
 'type': 'Lunar'}