V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
soratadori
V2EX  ›  Python

有必要为每一行数据创建一个实例吗?

  •  
  •   soratadori · 2016-10-04 18:32:27 +08:00 · 2829 次点击
    这是一个创建于 2977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需要操作的数据的结构如下,最后要输出回文件上(有序)

    key1, key2, key3, key4, key5

    v11, v12, v13, va14, v15

    v21, v22, v23, v24, v25

    v31, v32, v33, v34, v35

    我在看到有人是为每一行创建一个 instance ,把所有的 instance 都保存在列表里,要修改某些数据的时候就用 instance.key4=v44 这样的形式来修改。我觉得明明可以用字典来实现呀,为什么要这么复杂呢。

    所以我想知道这种为每行创建一个 instance 的写法有什么好处吗?

    另外,假如要用字典的形式来处理每一行,那我用 OrderedDict 是不是比自己再另外造一个表要好得多瞎搞要好很多(效率上)?

    第 1 条附言  ·  2016-10-04 21:12:29 +08:00
    再补充一下伪代码,应该怎么改进?(感觉好丑)


    ```


    class ABC

    class row_instance
    def __init__():
    # 这一段是嵌套比较好还是放在外面比较好?
    pass

    key_order = []
    data_order = []
    map[k1] = this_row # 用 k1 来定位这行

    def read()
    # 读取之后数据会以 instance 的形式 保存到上面 3 个变量里
    pass

    def some_operate_1()
    # 各种操作
    pass

    def some_operate_2()
    # 各种操作
    pass


    a = ABC()
    a.read(xxx)
    a.some_operate()

    ```

    假如一个文件里有多种不同结构的数据,如果把各种操作都写在一个类里(ABC),会显得很难看,如果我把不同结构的数据的操作分别放进各个类里如何?(嵌套, ABC 下一种结构一个类),这是种正常的写法吗
    第 2 条附言  ·  2016-10-04 23:06:23 +08:00
    →_→ 求代码格式的建议,自己写的感觉太丑陋了.....
    18 条回复    2016-10-06 17:03:58 +08:00
    cheetah
        1
    cheetah  
       2016-10-04 19:10:41 +08:00
    没能懂
    BingoXuan
        2
    BingoXuan  
       2016-10-04 19:22:55 +08:00
    个人觉得缺点在于每一增加一行就要创建一个新的 instance 。随着数据量增加,要添加的 instance 就越来越多,维护起来很麻烦,显得不够简洁。

    对于数据我一般都用 pandas 处理,感觉相对简便一点。
    reus
        3
    reus  
       2016-10-04 20:02:19 +08:00
    内存占用小一些,类实例比 dict
    binux
        4
    binux  
       2016-10-04 20:05:04 +08:00
    字典就不是 instance 了?! OrderedDict 就不是 instance 了?!
    soratadori
        5
    soratadori  
    OP
       2016-10-04 20:23:03 +08:00
    @binux 但是写起来不方便 0.0 就是想知道这种写法有啥好处。
    binux
        6
    binux  
       2016-10-04 20:32:09 +08:00
    @soratadori 有什么不方便的了?重载一个 __getitem__ 就一样 instance['key4'] 了,有什么区别?!还能增加方法,有什么不好?
    soratadori
        7
    soratadori  
    OP
       2016-10-04 20:32:59 +08:00
    @reus 从可读性,易维护性之类的角度来考虑的话呢?

    我发现不同的读取属性的方式,速度也有显著的不同。像 getattr() 比在实例里内置一个返回函数(instance.get())要快差不多 100%。那么应该鼓励用可读性最好的方式还是应该用比较严谨的方式?
    soratadori
        8
    soratadori  
    OP
       2016-10-04 20:43:47 +08:00
    @binux 额。。。你说的也没错
    soratadori
        9
    soratadori  
    OP
       2016-10-04 20:47:51 +08:00
    我后来也尝试过这种写法,对于严谨点的要求可能是比用字典要显得更优雅点,只是看上去不够直观,比如用 OrderedDict 能完成的事,用 instance 的话,就需要用列表排序+字典检索,所以我比较想知道一般普遍推荐用哪种方法,这两种方法从速度、可读性、易维护性的角度来考虑的话,有没有哪种有显著性的优势。
    reself
        10
    reself  
       2016-10-04 21:57:10 +08:00 via Android
    过早优化是万恶之源
    ruoyu0088
        11
    ruoyu0088  
       2016-10-04 22:06:42 +08:00
    如果键是可以用变量名表示的话,那么用实例比较方便。如果行数很多的话还可以通过__slots__节省内存。
    soratadori
        12
    soratadori  
    OP
       2016-10-04 23:02:31 +08:00
    @reself 这个脚本我已经写了很久了,但自己还是太菜了 →_→
    soratadori
        13
    soratadori  
    OP
       2016-10-04 23:05:42 +08:00
    @ruoyu0088 属性确实可以用变量名,但是跟据获取属性的方法的不同,速度也不一样。

    这 3 种方法你觉得哪种比较好, instance.key ; instance.get(), get()里调用 resturn self.key ; getattr()
    就我测试来说,后面一个总比前面一个快 1 倍,但丑陋程度也增加一倍。
    ruoyu0088
        14
    ruoyu0088  
       2016-10-05 06:31:41 +08:00
    测试有问题吧,怎么可能后面的比前面的快,下面是测试程序和结果:

    https://gist.github.com/ruoyu0088/d00e3a8970ce457175e49b17893157c2
    kaneg
        15
    kaneg  
       2016-10-05 09:20:09 +08:00 via iPhone
    在程序跑起来之前不要过早考虑性能的问题,而应该用最容易理解的方式实现。
    reself
        16
    reself  
       2016-10-06 09:43:56 +08:00 via Android
    @soratadori 个人感觉这段代码的瓶颈应该在于磁盘 IO ,因此,就时间上,很可能 class 和 dict 两种实现的差异并不大。空间上,算法不变的话,消耗也差不多,顶多多个常量。不妨测试一下这两种实现的时间和空间差异~
    还有,有个观点,调用者不需要关心被调用的方法是如何实现的,调用者只关心方法实现的功能,至于实现的机制、效率调用者不需要也没必要去关心。简言之就是高内聚低耦合。
    reself
        17
    reself  
       2016-10-06 09:49:43 +08:00 via Android
    提高可读性是肯定要牺牲效率的,两者之间取好平衡点折衷处理。一切皆对象。
    BiggerLonger
        18
    BiggerLonger  
       2016-10-06 17:03:58 +08:00
    为啥不用 NamedTuple 呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1180 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 18:41 · PVG 02:41 · LAX 10:41 · JFK 13:41
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.