Python 板


LINE

※ 引述《jasonhsu14 (14号星期五的杰森)》之铭言: : H1=Human1() : print(H1.BMI())得到当初创建类别时的预设或输入的数字 : print(H1.BMI(170,80))时,得到不一样的结果 : 有想过直接在 def BMI(self, h=160, w=50)这样去写 : 但这样又等於重复做了跟__init__一样的事情 : 所以想询问有无办法让BMI变成一个 : 不输入的话就会根据最一开始创建类别的预设(或输入)数值 : 但也可以让BMI自己另外输入想要的数字 忽然觉得想说的多了点,还是回文好了。虽然推文给了一个回答,但我觉得最好 还是从概念上来处理这个问题。 H1.BMI() 这写法很直觉,就是得到H1这个实体本身的BMI,没有问题。但是: H1.BMI(170, 80) 请问你觉得这是什麽概念呢?叫H1这个人帮你算算170/80的人BMI是多少? 你可以发现,这两个用法的概念是冲突的。前者把H1当作一个有BMI的实体,後 者却只是一个计算BMI的计算器。 那麽我的建议是,应该把实体跟计算器的角色分开来。这个计算器谁来负责呢? 我认为是Human1 class本身,把计算方法定义成Human1的一个静态方法。当我们要计 算任意一组资料的BMI时,我们呼叫: Human1.cal_BMI(170, 80) 这个cal_BMI()可以定义为: @classmethod def cal_BMI(cls, h, w): # 计算并return BMI 当我们要得知一个实体H1本身的BMI时,我们呼叫: H1.BMI() 而这个BMI()则定义为: def BMI(self): return Human1.cal_BMI(self.h, self.w) 这样,我们就既不需要在两处处理default值(__init__跟BMI),也兼顾了code 的重用性,同时让实体跟class本体的角色更明确。同时,也不需要写烦人的逻辑来 判断输入值是什麽情况、要用内部值或外部值等等。 BMI要修改计算方式,我们只需要改动cal_BMI(),除非引入了其他参数或要改变 实体与类的计算连接方式(比如说,公开测量时的cal_BMI都是很公正的,但是要让 每个人自报BMI时都故意低报一点,就像NBA球员偷偷高报身高XD)才会动到BMI()。 -- 「可是你......不是天使吗?」 「天使?」她缓缓的转过头来,用悲伤的表情。「天使,只不过是神创造出来的 不死玩偶。」 「而神,也只不过是诅咒下的伪善使者。」 --星.幻.梦的传说 --



※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 111.248.150.42 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1587015592.A.42B.html ※ 编辑: ddavid (111.248.150.42 台湾), 04/16/2020 13:43:12
1F:推 cuteSquirrel: 推 04/16 13:46
2F:→ jasonhsu14: 谢谢你的回答,现在才看到XD 04/16 13:53
3F:推 drysor: 推 04/16 15:32
4F:推 a0956072892: 推个 04/16 15:43
5F:推 s860134: 物件导向 04/17 20:03
6F:推 TuCH: 想问一下用Human1.cal_BMI 还是 self.cal_BMI 比较好呢 04/19 16:40
我认为选择 Human1.cal_BMI 比较好。概念上也就是说,这边是每个人都依循这 个人类定义的标准计算方式给出BMI,他们不是「每个人用自己的方式计算」,所以 call的是类别静态版本较符合这概念。 单从程式语言写作而言也是建议如此做,即便Python确实可以让你透过实体去呼 叫静态方法。 ※ 编辑: ddavid (114.36.173.238 台湾), 04/19/2020 19:52:12
7F:→ stucode: 我有不同的看法,在这个例子中 BMI 的计算并无涉及类别或 04/19 23:32
8F:→ stucode: 类别变数,因此 cal_BMI() 应该写成纯函数比较合适。如果 04/19 23:32
9F:→ stucode: 想把它放进 Human1 类别里,用 @staticmethod 会是比较好 04/19 23:32
10F:→ stucode: 的做法。假如想保留弹性空间,例如你觉得未来有个 04/19 23:33
11F:→ stucode: 「新人类」类别会继承自 Human1,而这个新类别的 BMI 04/19 23:33
12F:→ stucode: 计算会参考到类别变数,所以使用 @classmethod 的话, 04/19 23:33
13F:→ stucode: 呼叫部分应写成 self.cal_BMI() 才能让方法覆载正确发挥 04/19 23:33
14F:→ stucode: 作用。写成 Human1.cal_BMI() 的话反而会锁死在基础类别 04/19 23:34
其实我确实是有想过一些不同使用情境或未来扩展会导致应该使用不同设计的情 况。 不过我认为就这个例子可以单纯化,所以就只给了基本的简单设计。 基本上我认为与其过度设计不如等用到了再refactoring,工作上有深刻体验。 所以事实上在原Po一开始那篇直接硬用if解决的方式,也未必有什麽不好。 至於你提到@staticmethod来取代@classmethod,你是对的。我不是为了扩展性 ,只是直觉用了@classmethod,但其实这边没有必要使用cls,所以@staticmethod确 实比较好XD ※ 编辑: ddavid (1.160.87.162 台湾), 04/20/2020 12:46:07
15F:推 Arescrow: 推 04/20 15:21
16F:推 stucode: 补个推 04/20 22:35







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:WOW站内搜寻

TOP