Python类属于数据和重构

时间:2017-10-06 11:10:55

标签: python

关于以下问题,我找不到好的建议: 我正在创建一个PyQt应用程序,并希望每个项目在一个文件中保存持久数据(没有服务器,没有SQL)。

我决定创建一个包含属性的类,然后创建instanciate对象。然后我将这些对象存储在一个列表中(预期< 500个对象和大多数项目< 60个对象)。最后,我使用了一种pickle模块将数据存储在驱动器上。

  1. 这是一个非常糟糕的事情(类对象比dict列表更容易理解......)
  2. 我创建了以下代码

    class Item: position = ['key','a','b','c'] def__init__(self, key=None, a=None, b=None, c=None): self.key = key self.a = a self.b = b self.c = c 有没有办法避免重复k,a,b,c(我可能会在以后添加很多)

3 个答案:

答案 0 :(得分:2)

有没有好的做法而不是存储实例列表?

您指定的数据量不是很高,因此应该可以使用类的实例列表,但有更好的方法来存储此信息。

  1. 正如您已经说过的dict列表。
  2. namedtuple s。
  3. 的列表

    字典

    将dict伪装为objetc

    如果选择第一个选项,则可以创建一个充当类构造函数的函数来保持类似的语法:

    def Item(key=None, a=None, b=None, c=None):
        return {
            "key": key,
            "a": a,
            "b": b,
            "c": c
        }
    

    额外的抽象级别增加了灵活性

    您甚至可以通过传递键列表来创建一个生成此类函数的函数:

    def ItemGenerator(*spec):
        def f(*args, **kwargs):
            args = dict(enumerate(args))
            return {k: kwargs.get(k, args.get(i, None)) for i, k in enumerate(spec)}
        return f
    

    ItemGenerator()函数接受任意数量的字符串作为直接参数,而无需将它们包装到列表中。如果您只想提供一个列表作为参数,请从*中删除def ItemGenerator(*spec):。它创建一个新函数,返回一个字典,其字符串是传递给ItemGenerator的参数,其值为None作为默认值。它会像这样使用:

      

    注意: python中的dicts 无序,因此您可以在将结果打印到屏幕时以不同的顺序看到参数,但它们的值将是分配正确。为了清楚起见,我列出了他们的订单。

    Item = ItemGenerator("key", "a", "b", "c")
    
    # All default values
    Item()                     # {"key": None, "a": None, "b": None, "c": None}
    # Named and positional arguments
    Item(a=1)                  # {"key": None, "a": 1,    "b": None, "c": None}
    Item(1)                    # {"key": 1,    "a": None, "b": None, "c": None}
    Item(key=1, a=2, b=3, c=4) # {"key": 1,    "a": 2,    "b": 3,    "c": 4   }
    Item(1, 2, 3, 4, a=5)      # {"key": 1,    "a": 5,    "b": 3,    "c": 4   }
    # Extra arguments
    Item(1, 2, 3, 4, 5)        # {"key": 1,    "a": 2,    "b": 3,    "c": 4   }
    Item(a=1, d=2)             # {"key": None, "a": 1,    "b": None, "c": None}
    

    Item函数在开始时通过指定最终字典将具有的键生成,然后可以根据需要多次使用。调用它时,不提供为生成器指定的参数之一将其值设置为None。可以使用位置和命名参数,但是命名参数可以优先使用。提供额外的位置参数或指定参数不在规范中,将无声地省略它们。

      

    更多技术说明:生成器返回一个函数,它捕获位置和命名(关键字)参数,并将位置参数转换为按位置索引的字典,以便能够使用dict.get(attrName, defaultValue)。然后它使用一个理解来返回一个dict,其键是生成器中定义的那些,其值首先在命名参数中搜索,其次在位置参数中,如果两个都缺失则默认为None。然后返回生成的函数。

    Namedtuple

    您可以使用类似的方法来制作返回元组的函数,而不是使用dict,而是namedtuplePython2.7Python3.6)。或函数生成器,它返回一个函数,当被调用时返回一个namedtuple。它只是改变容器。

    我可以自动为类分配属性吗?

    是的,您可以按照其他人的回答:IberêVivek Pandey

答案 1 :(得分:1)

您可以这样做:

In [47]: x = df.groupby(['Col2','Col3','WeekNumber']) \
               .agg({'Value1':'cumsum', 'Value2':'cumsum','WeekNumber':'cumcount'})

In [48]: x['WeekNumber'] += df['WeekNumber']

In [49]: x
Out[49]:
   Value1  Value2  WeekNumber
0       8       3           1
1       5       1           2
2       1       2           3
3      12       9           2
4       9       8           3
5       8       3           3
6       7       2           4
7       2       3           1
8      16       9           4

这会使你的课堂学习非常难以阅读。

答案 2 :(得分:1)

  1. 不,这不是一件坏事

  2. 你可以避免这种情况:

  3. class Item:
        params = {}
        def __init__(self, **kwargs):
            self.params = kwargs
    

    现在,你可以做到

    item = Item(first_name='Sylvain', last_name='Page')