写这样一个简单的类用到 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 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, 单一职责原则. 程序是对现实的模拟, 你现实是怎么样, 程序就能怎么样. 你现实中为人处事很有条理, 规矩, 那么你程序也能写得这么好. |
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 1
主要是 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 2016-05-24 09:31:22 +08:00
那个,你把 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 ,可读性比较差
|