写这样一个简单的类用到 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)
![]() | 1 SlipStupig 2016-05-23 16:24:42 +08:00 self 是隐含调用类似 this->obj 这种语法,如果不想用 self 可以声明成静态成员函数,你就不需要写了,同样你无法调用其它非静态成员 |
2 BOYPT 2016-05-23 16:27:51 +08:00 要不去学 perl 吧(坏笑 |
![]() | 3 NullMan 2016-05-23 16:34:00 +08:00 ![]() 建议: 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, 单一职责原则. 程序是对现实的模拟, 你现实是怎么样, 程序就能怎么样. 你现实中为人处事很有条理, 规矩, 那么你程序也能写得这么好. |
![]() | 4 clino 2016-05-23 16:39:07 +08:00 我觉得这是个挺好的做法啊,把面向对象的做法明白展示出来了 其实 lua 也是,不过 lua 可以有语法糖来省掉函数声明里的参数 |
![]() | 5 huanghua123 OP @BOYPT 其实我也想感受下七周七语言。。 |
![]() | 6 huanghua123 OP @NullMan 感谢建议 |
![]() | 7 huanghua123 OP @clino 意思上确实清晰很多。实际上写起来,却有些繁琐。各有取舍吧 |
![]() | 8 NullMan 2016-05-23 16:45:29 +08:00 @huanghua123 No, No, 写起来, 看起来繁琐, 但是你读起来, 维护起来, 轻松得不得了. 不信, 你试试按我的方式写一个, 然后把你我的版本, 给你同事看看. 看看他会觉得哪个最舒服? 如果你程序真的就如上那么简单而且. 那么把这三个类, 写到一个文件里. 那么在编写方面. 只比你的版本繁琐那么一丢丢, 只有一丢丢而已. 但是其他方面, 远远超过你的版本了. 如果是大系统里的一部分, 相信, 拆开来搞. 另外, 你这程序, 看起来是在搞全自动炒股机器人? 可否带带我呀? |
![]() | 9 huanghua123 OP @NullMan 我并不是指面向对象繁琐,我是指 self 繁琐,不过也还接受,纯粹吐槽。这其实只是 berkeley 的 homework 。。 |
![]() | 10 NullMan 2016-05-23 16:59:42 +08:00 |
![]() | 11 aaaron7 2016-05-23 17:09:40 +08:00 我也习惯用类似这样的驼峰命名,被 IDE 各种 warning ……让我改小写。。 |
![]() | 12 huanghua123 OP @NullMan 。。我不是 berkeley 的。你这么说我就不服了。这明明是个自动售货机,你非要说成炒股机器人... |
![]() | 13 huanghua123 OP @aaaron7 肯定是 java 过来的。。 |
![]() | 14 NullMan 2016-05-23 17:13:32 +08:00 @huanghua123 我勒个去, 居然是自动售货机..... 更坏坏说一句: 你这侧面证明了你写得多**, 居然能让我认为是个自动炒股机器人的部件咧.... |
![]() | 15 huanghua123 OP """A vending machine that vends some product for some price.""" 你在逗我 |
![]() | 16 NullMan 2016-05-23 17:14:52 +08:00 @huanghua123 哦, 我说写这程序的人. |
17 ma125125t 2016-05-23 17:33:47 +08:00 @NullMan 说的没错,看这变量名取的确实不明所以。 stockName 理解为股票名, stockPrice 理解为股票价格是很正常的了。代码写得好不好,能让别人第一时间上手是很重要的一点。 |
18 jiang42 2016-05-23 17:45:44 +08:00 via iPhone 感觉 class 的注释很多余。。。 |
![]() | 19 lightening 2016-05-23 17:50:53 +08:00 你的编辑器会自动帮你写的吧,一般你写 def<tag> 他就出来了。 |
20 scriptfans 2016-05-23 17:54:32 +08:00 不加 self 的话,你让解释器如何分辨你是想声明局部变量呢,还是想访问属性? |
![]() | 21 congeec 2016-05-23 17:54:56 +08:00 via iPhone 写起来并不繁琐,你需要 vim |
![]() | 22 cxh116 2016-05-23 17:57:38 +08:00 有比较好一点,在 ruby 里面这是一个比较容易踩的坑. puts name,这个 name 变量,如果没有,则从自动从 self 对象上面找. 习惯后,就有可能 name = 'test' 这样写,但这样赋值,变成给 name 本地变量赋值,而不是实例属性赋值,有点坑. |
23 a412739861 2016-05-23 18:19:37 +08:00 @aaaron7 Objective-C 的风格么,不过我感觉驼峰的写法不容易读……还是下划线的好读。当然 Apple 里面都是驼峰,自然为了一致,都写驼峰了。 |
24 introom 2016-05-23 18:22:01 +08:00 via Android self 是很冗余,一个语言不是什么都好可惜现在回不去了,不可能说我们把 self 作为一个关键字。 |
25 ayaseangle 2016-05-23 18:40:02 +08:00 ![]() 主要是 python 的 oo 特性是随着后期发展慢慢加进去的,所以看上去不是那么和谐。。。 |
![]() | 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 |
![]() | 27 eric6356 2016-05-23 19:16:03 +08:00 Explicit is better than implicit. https://www.python.org/dev/peps/pep-0020/ |
![]() | 28 L2AKnG8GXx60bc6P 2016-05-23 20:02:30 +08:00 php 的 this 和 self 岂不美哉? |
![]() | 29 SlipStupig 2016-05-23 20:24:58 +08:00 @scriptfans 用 this 或者用声明 thiscall 修饰,在虚拟机里面采用调用方来维持堆栈平衡, python 设置的时候就没想过用程序员来平衡虚拟机堆栈 |
30 tempdban 2016-05-23 20:47:30 +08:00 via Android 我还觉得$贼傻逼呢,该用不还是得用 |
31 weyou 2016-05-23 23:21:07 +08:00 加上 self 更加清晰, C++里面不需要 this ,往往要用别的方式来表明这是个类成员变量,比如加上 m_前缀。 |
![]() | 32 incompatible 2016-05-23 23:24:21 +08:00 via iPhone @Mutoo 你说的并不能解答楼主的问题,楼主问的是 self 是否冗余。假设 Java 显示规定必须使用或必须不使用 this.来调用成员方法或引用成员变量,看起来显然比 python 清爽多了。 |
![]() | 33 msg7086 2016-05-23 23:48:45 +08:00 觉得繁琐写 Ruby 去啊。 Python 的精髓就是繁琐…… |
![]() | 34 zijikai 2016-05-24 00:29:43 +08:00 对于新手来说,至少逻辑上理解起来轻松多了。 |
35 noli 2016-05-24 01:55:15 +08:00 via iPhone 在 python 中 self 是必须的,否则二义性会毁掉这门语言。我很奇怪居然有人说 self 是冗余的? |
36 SharkIng 2016-05-24 02:01:22 +08:00 via iPhone self 主要是方便日后使用 class 里面的变量 感觉有点像 java 里面的 public 变量 |
![]() | 38 ligyxy 2016-05-24 04:43:57 +08:00 居然不止一个人说变量名不明确,心疼楼主 |
![]() | 39 jamiesun 2016-05-24 07:01:50 +08:00 self,这是一个必须的东西,也是 python 严谨性的一个体现 |
![]() | 40 jamiesun 2016-05-24 07:04:25 +08:00 不喜欢 self ,你可以用 this 啊 class A: ...: def __init__(this): ...: print this.__class__ |
41 7jmS8834H50s975y 2016-05-24 07:08:54 +08:00 我觉得 java 方法调用的模式就比较好. |
![]() | 42 cc7756789 2016-05-24 07:27:45 +08:00 你是没用过 go 的错误处理吧。如果你希望其他语言像 CoffeeScript 一样把 JS 的括号都省了,那么还是转行算了,代码的清晰准确比多写几个跟踪到数据的指针变量符号重要多了。 |
![]() | 43 KyL 2016-05-24 09:26:17 +08:00 self 是程序员自己起的一个变量名,它之所以能起到 self 的作用,只是因为它是类方法的第一个参数。你可以把 self 改成任意变量名。 我觉得确实有些多此一举,更好的方法是把 self 设为 py 的一个关键字,就像 C++/Java 中的 this 一样。 |
![]() | 44 realpg PRO 那个,你把 stockNumber 改成 inStockCount 就没歧义了 number 单独使用并没有计数的意思,或者说无法强调计数 in stock 和 stock 是两个完全不同的概念 |
45 RqPS6rhmP3Nyn3Tm 2016-05-24 10:11:47 +08:00 IDE 都自动搞定了,读起来容易很多 |
![]() | 46 ChiangDi 2016-05-24 10:15:18 +08:00 via Android 这是个历史缺陷,作者都说了 |
![]() | 47 2owe 2016-05-24 11:52:03 +08:00 兼顾便利性和可读性是坠吼滴!只能偏袒一方的话,可读性优先。 |
48 robinshi2010 2016-05-24 13:51:13 +08:00 @NullMan 觉得建议不错。感谢。 |
![]() | 49 stevenhu888 2016-05-24 14:06:03 +08:00 @NullMan 老兄所言甚是 |
50 misaka15 2016-05-25 10:18:16 +08:00 类似于 Swift 一样,省略掉 self ,可读性比较差 |