大家写 python 的时候不会觉得 self 有点冗余吗 - V2EX
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
huanghua123
V2EX    Python

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

  •  
  •   huanghua123 2016-05-23 16:21:42 +08:00 7964 次点击
    这是一个创建于 3431 天前的主题,其中的信息可能已经有所发展或是发生改变。

    写这样一个简单的类用到 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 条回复    2016-05-25 10:18:16 +08:00
    SlipStupig
        1
    SlipStupig  
       2016-05-23 16:24:42 +08:00
    self 是隐含调用类似 this->obj 这种语法,如果不想用 self 可以声明成静态成员函数,你就不需要写了,同样你无法调用其它非静态成员
    BOYPT
        2
    BOYPT  
       2016-05-23 16:27:51 +08:00
    要不去学 perl 吧(坏笑
    NullMan
        3
    NullMan  
       2016-05-23 16:34:00 +08:00   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  
       2016-05-23 16:39:07 +08:00
    我觉得这是个挺好的做法啊,把面向对象的做法明白展示出来了
    其实 lua 也是,不过 lua 可以有语法糖来省掉函数声明里的参数
    huanghua123
        5
    huanghua123  
    OP
       2016-05-23 16:39:12 +08:00
    @BOYPT 其实我也想感受下七周七语言。。
    huanghua123
        6
    huanghua123  
    OP
       2016-05-23 16:39:41 +08:00
    @NullMan 感谢建议
    huanghua123
        7
    huanghua123  
    OP
       2016-05-23 16:41:01 +08:00
    @clino 意思上确实清晰很多。实际上写起来,却有些繁琐。各有取舍吧
    NullMan
        8
    NullMan  
       2016-05-23 16:45:29 +08:00
    @huanghua123 No, No, 写起来, 看起来繁琐, 但是你读起来, 维护起来, 轻松得不得了. 不信, 你试试按我的方式写一个, 然后把你我的版本, 给你同事看看. 看看他会觉得哪个最舒服?

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

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


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

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

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

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

    number 单独使用并没有计数的意思,或者说无法强调计数 in stock 和 stock 是两个完全不同的概念
    RqPS6rhmP3Nyn3Tm
        45
    RqPS6rhmP3Nyn3Tm  
       2016-05-24 10:11:47 +08:00
    IDE 都自动搞定了,读起来容易很多
    ChiangDi
        46
    ChiangDi  
       2016-05-24 10:15:18 +08:00 via Android
    这是个历史缺陷,作者都说了
    2owe
        47
    2owe  
       2016-05-24 11:52:03 +08:00
    兼顾便利性和可读性是坠吼滴!只能偏袒一方的话,可读性优先。
    robinshi2010
        48
    robinshi2010  
       2016-05-24 13:51:13 +08:00
    @NullMan 觉得建议不错。感谢。
    stevenhu888
        49
    stevenhu888  
       2016-05-24 14:06:03 +08:00
    @NullMan 老兄所言甚是
    misaka15
        50
    misaka15  
       2016-05-25 10:18:16 +08:00
    类似于 Swift 一样,省略掉 self ,可读性比较差
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3485 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 10:40 PVG 18:40 LAX 03:40 JFK 06:40
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86