推荐学习书目
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
huanghua123
V2EX  ›  Python

大家写 python 的时候不会觉得 self 有点冗余吗

  •  
  •   huanghua123 · May 23, 2016 · 8419 views
    This topic created in 3667 days ago, the information mentioned may be changed or developed.

    写这样一个简单的类用到 n 多 self ,个人觉得有点冗余,大家什么感觉?我也是初学,或者有好的方法可以避免?

    class VendingMachine:
        """A vending machine that vends some product for some price."""
        def __init__(self,stockName,stockPrice):
            self.stockName = stockName
            self.stockPrice = stockPrice
            self.stockNumber = 0
            self.balance = 0
    
        def vend(self):
            if self.stockNumber == 0:
                return "Machine is out of stock."
            elif self.balance < self.stockPrice:
                return 'You must deposit $' + str(self.stockPrice - self.balance) + ' more.'
            else:
                self.stockNumber -= 1
                change = self.balance - self.stockPrice;
                self.balance = 0
                if change == 0:
                    return 'Here is your candy.'
                else:
                    return 'Here is your candy and $'+ str(change) +' change.'
    
    
        def deposit(self,amount):
            self.balance += amount
    
            if(self.stockNumber == 0):
                return 'Machine is out of stock. Here is your $' + str(self.balance) + '.'
    
            return "Current balance: $" + str(self.balance)
    
        def restock(self,stockNumber):
            self.stockNumber += stockNumber
            return "Current candy stock: " + str(self.stockNumber)
    
    50 replies    2016-05-25 10:18:16 +08:00
    SlipStupig
        1
    SlipStupig  
       May 23, 2016
    self 是隐含调用类似 this->obj 这种语法,如果不想用 self 可以声明成静态成员函数,你就不需要写了,同样你无法调用其它非静态成员
    BOYPT
        2
    BOYPT  
       May 23, 2016
    要不去学 perl 吧(坏笑
    NullMan
        3
    NullMan  
       May 23, 2016   ❤️ 5
    建议:
    1, 变量采用下划线, 跟 Python 核心类库一致.
    2, stockNumber 改为 number_of_stocks. 不看完你代码, 还以为指的的股票代码呢.
    3, VendingMachine 改为 AutoStockRobot.
    4, balance 存放到你另外一个类(Account).
    5, 跟股票相关的, 放到另外一个类, 比如 Stock.
    6, AutoStockRobot 就有 account, stocks 这俩主要变量, 和三个那 restock, deposit, vend 这三动作.

    总结: 你至少要有三个类, AutoStockRobot, Account, Stock, 单一职责原则. 程序是对现实的模拟, 你现实是怎么样, 程序就能怎么样. 你现实中为人处事很有条理, 规矩, 那么你程序也能写得这么好.
    clino
        4
    clino  
       May 23, 2016
    我觉得这是个挺好的做法啊,把面向对象的做法明白展示出来了
    其实 lua 也是,不过 lua 可以有语法糖来省掉函数声明里的参数
    huanghua123
        5
    huanghua123  
    OP
       May 23, 2016
    @BOYPT 其实我也想感受下七周七语言。。
    huanghua123
        6
    huanghua123  
    OP
       May 23, 2016
    @NullMan 感谢建议
    huanghua123
        7
    huanghua123  
    OP
       May 23, 2016
    @clino 意思上确实清晰很多。实际上写起来,却有些繁琐。各有取舍吧
    NullMan
        8
    NullMan  
       May 23, 2016
    @huanghua123 No, No, 写起来, 看起来繁琐, 但是你读起来, 维护起来, 轻松得不得了. 不信, 你试试按我的方式写一个, 然后把你我的版本, 给你同事看看. 看看他会觉得哪个最舒服?

    如果你程序真的就如上那么简单而且. 那么把这三个类, 写到一个文件里. 那么在编写方面. 只比你的版本繁琐那么一丢丢, 只有一丢丢而已. 但是其他方面, 远远超过你的版本了.

    如果是大系统里的一部分, 相信, 拆开来搞.


    另外, 你这程序, 看起来是在搞全自动炒股机器人? 可否带带我呀?
    huanghua123
        9
    huanghua123  
    OP
       May 23, 2016
    @NullMan 我并不是指面向对象繁琐,我是指 self 繁琐,不过也还接受,纯粹吐槽。这其实只是 berkeley 的 homework 。。
    NullMan
        10
    NullMan  
       May 23, 2016
    @huanghua123 坏坏地说一句: 伯克利的学生写的程序这么烂, 让我这一个初中文化的程序员满满的成就感.

    逃 :)
    aaaron7
        11
    aaaron7  
       May 23, 2016
    我也习惯用类似这样的驼峰命名,被 IDE 各种 warning ……让我改小写。。
    huanghua123
        12
    huanghua123  
    OP
       May 23, 2016
    @NullMan 。。我不是 berkeley 的。你这么说我就不服了。这明明是个自动售货机,你非要说成炒股机器人...
    huanghua123
        13
    huanghua123  
    OP
       May 23, 2016
    @aaaron7 肯定是 java 过来的。。
    NullMan
        14
    NullMan  
       May 23, 2016
    @huanghua123 我勒个去, 居然是自动售货机..... 更坏坏说一句: 你这侧面证明了你写得多**, 居然能让我认为是个自动炒股机器人的部件咧....
    huanghua123
        15
    huanghua123  
    OP
       May 23, 2016
    """A vending machine that vends some product for some price.""" 你在逗我
    NullMan
        16
    NullMan  
       May 23, 2016
    @huanghua123 哦, 我说写这程序的人.
    ma125125t
        17
    ma125125t  
       May 23, 2016
    @NullMan 说的没错,看这变量名取的确实不明所以。 stockName 理解为股票名, stockPrice 理解为股票价格是很正常的了。代码写得好不好,能让别人第一时间上手是很重要的一点。
    jiang42
        18
    jiang42  
       May 23, 2016 via iPhone
    感觉 class 的注释很多余。。。
    lightening
        19
    lightening  
       May 23, 2016
    你的编辑器会自动帮你写的吧,一般你写 def<tag> 他就出来了。
    scriptfans
        20
    scriptfans  
       May 23, 2016
    不加 self 的话,你让解释器如何分辨你是想声明局部变量呢,还是想访问属性?
    congeec
        21
    congeec  
       May 23, 2016 via iPhone
    写起来并不繁琐,你需要 vim
    cxh116
        22
    cxh116  
       May 23, 2016
    有比较好一点,在 ruby 里面这是一个比较容易踩的坑.

    puts name,这个 name 变量,如果没有,则从自动从 self 对象上面找.
    习惯后,就有可能 name = 'test' 这样写,但这样赋值,变成给 name 本地变量赋值,而不是实例属性赋值,有点坑.
    a412739861
        23
    a412739861  
       May 23, 2016
    @aaaron7 Objective-C 的风格么,不过我感觉驼峰的写法不容易读……还是下划线的好读。当然 Apple 里面都是驼峰,自然为了一致,都写驼峰了。
    introom
        24
    introom  
       May 23, 2016 via Android
    self 是很冗余,一个语言不是什么都好可惜现在回不去了,不可能说我们把 self 作为一个关键字。
    ayaseangle
        25
    ayaseangle  
       May 23, 2016   ❤️ 1
    主要是 python 的 oo 特性是随着后期发展慢慢加进去的,所以看上去不是那么和谐。。。
    Mutoo
        26
    Mutoo  
       May 23, 2016
    python 语言在发明的时候就规定一件事只有一种做法( There's Only One Way To Do It )。像 java 那样,省略或不省略 this 两种写法就违背了这个守则,详见:
    https://wiki.python.org/moin/TOOWTDI
    eric6356
        27
    eric6356  
       May 23, 2016
    Explicit is better than implicit.
    https://www.python.org/dev/peps/pep-0020/
    L2AKnG8GXx60bc6P
        28
    L2AKnG8GXx60bc6P  
       May 23, 2016
    php 的 this 和 self 岂不美哉?
    SlipStupig
        29
    SlipStupig  
       May 23, 2016
    @scriptfans 用 this 或者用声明 thiscall 修饰,在虚拟机里面采用调用方来维持堆栈平衡, python 设置的时候就没想过用程序员来平衡虚拟机堆栈
    tempdban
        30
    tempdban  
       May 23, 2016 via Android
    我还觉得$贼傻逼呢,该用不还是得用
    weyou
        31
    weyou  
       May 23, 2016
    加上 self 更加清晰, C++里面不需要 this ,往往要用别的方式来表明这是个类成员变量,比如加上 m_前缀。
    incompatible
        32
    incompatible  
       May 23, 2016 via iPhone
    @Mutoo 你说的并不能解答楼主的问题,楼主问的是 self 是否冗余。假设 Java 显示规定必须使用或必须不使用 this.来调用成员方法或引用成员变量,看起来显然比 python 清爽多了。
    msg7086
        33
    msg7086  
       May 23, 2016
    觉得繁琐写 Ruby 去啊。
    Python 的精髓就是繁琐……
    zijikai
        34
    zijikai  
       May 24, 2016
    对于新手来说,至少逻辑上理解起来轻松多了。
    noli
        35
    noli  
       May 24, 2016 via iPhone
    在 python 中 self 是必须的,否则二义性会毁掉这门语言。我很奇怪居然有人说 self 是冗余的?
    SharkIng
        36
    SharkIng  
       May 24, 2016 via iPhone
    self 主要是方便日后使用 class 里面的变量 感觉有点像 java 里面的 public 变量
    markx
        37
    markx  
       May 24, 2016
    @ma125125t 看到类名是 VendingMachine , 你就该知道这个跟股票没关系了。
    ligyxy
        38
    ligyxy  
       May 24, 2016
    居然不止一个人说变量名不明确,心疼楼主
    jamiesun
        39
    jamiesun  
       May 24, 2016
    self,这是一个必须的东西,也是 python 严谨性的一个体现
    jamiesun
        40
    jamiesun  
       May 24, 2016
    不喜欢 self ,你可以用 this 啊

    class A:
    ...: def __init__(this):
    ...: print this.__class__
    7jmS8834H50s975y
        41
    7jmS8834H50s975y  
       May 24, 2016
    我觉得 java 方法调用的模式就比较好.
    cc7756789
        42
    cc7756789  
       May 24, 2016
    你是没用过 go 的错误处理吧。如果你希望其他语言像 CoffeeScript 一样把 JS 的括号都省了,那么还是转行算了,代码的清晰准确比多写几个跟踪到数据的指针变量符号重要多了。
    KyL
        43
    KyL  
       May 24, 2016
    self 是程序员自己起的一个变量名,它之所以能起到 self 的作用,只是因为它是类方法的第一个参数。你可以把 self 改成任意变量名。
    我觉得确实有些多此一举,更好的方法是把 self 设为 py 的一个关键字,就像 C++/Java 中的 this 一样。
    realpg
        44
    realpg  
    PRO
       May 24, 2016
    那个,你把 stockNumber 改成 inStockCount 就没歧义了

    number 单独使用并没有计数的意思,或者说无法强调计数 in stock 和 stock 是两个完全不同的概念
    RqPS6rhmP3Nyn3Tm
        45
    RqPS6rhmP3Nyn3Tm  
       May 24, 2016
    IDE 都自动搞定了,读起来容易很多
    ChiangDi
        46
    ChiangDi  
       May 24, 2016 via Android
    这是个历史缺陷,作者都说了
    2owe
        47
    2owe  
       May 24, 2016
    兼顾便利性和可读性是坠吼滴!只能偏袒一方的话,可读性优先。
    robinshi2010
        48
    robinshi2010  
       May 24, 2016
    @NullMan 觉得建议不错。感谢。
    stevenhu888
        49
    stevenhu888  
       May 24, 2016
    @NullMan 老兄所言甚是
    misaka15
        50
    misaka15  
       May 25, 2016
    类似于 Swift 一样,省略掉 self ,可读性比较差
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2888 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 106ms · UTC 14:57 · PVG 22:57 · LAX 07:57 · JFK 10:57
    ♥ Do have faith in what you're doing.