|
发表于 2025-9-28 17:37:02
|
显示全部楼层
1)为什么这段 __init__ 不能省?
- class fulltime_staff(staff):
- def __init__(self, name, ID, monthly_salary):
- super().__init__(name, ID)
- self.monthly_salary = monthly_salary
复制代码
子类如果新增了属性(这里是 monthly_salary),就必须自己实现 __init__ 去接收它,并在里面先调用父类的 __init__ 初始化通用字段。
如果你省略这段,子类会继承父类的 __init__(self, name, ID)。
你若按老师的用法传三参:fulltime_staff("张三", 1001, 12000) → 会直接报 TypeError: __init__() takes 3 positional arguments but 4 were given。
你若只传两参:fulltime_staff("张三", 1001) → 对象里根本没有 monthly_salary,之后访问或计算会 AttributeError。
2)兼职 D_salary 为什么不用每次都 float()?
关键在于在入口处就把数据变成数字。只要在 __init__ 里把 work_days 和 daily_salary 转成 int/float 存起来,那么:
- self.daily_salary * self.work_days
复制代码
就是“数字×数字”,不会出现“字符串相乘”的问题。
真正容易出错的情况是:从输入拿到的是字符串,又没有在 __init__ 转换;
这时用到再 float() 就会很乱,还可能不小心做成了 int * str 的“重复字符串”。
在构造函数里做一次类型转换,计算处就干干净净。
3)你的 f"..." 为何被让我去掉 {}?
你写的是:
- print(f"工资: float({self.work_days}) * float({daily_salary}))
复制代码
这其实只是把字符串“float(…) * float(…)”打印出来,括号还不配对,计算根本没发生。
f"..." 里花括号 {} 的用法是“把已算好的表达式的值插到字符串里”。
要么:
- pay = float(self.work_days) * float(self.daily_salary)
- print(f"工资: {pay}")
复制代码
要么干脆不加 f-string,直接 print("工资:", pay)。
另外你的方法签名 D_salary(self, daily_salary) 不该再收一个 daily_salary 参数,应当用对象属性;
不然极易与 self.daily_salary 搞混。
你这段代码里的关键错误一览(逐条点名)
falltime_staff 拼写错误(应是 fulltime_staff)。
parttime_staff.__init__ 写成了 _init__(少一个下划线,构造函数根本不会被调用)。
super().__init__(name, staff) 传错了,应是 (name, ID)。
self.daily 与 self.daily_salary 混用,属性名不一致。
D_salary(self, daily_salary) 不应再收参数,直接用 self.daily_salary。
你的 M_salary(self, mounthly_salary) 既拼写错(monthly),也不应在方法里再收月薪参数;月薪应在构造时定好;而且方法里打印了一个字符串字面量 "float(self.ID)*3",这不会算任何东西。
info_print(self, print_way) 这个参数 print_way 并未使用,可以删掉。
可运行、结构清晰的参考实现
- """HR Department Programming"""
- class Staff:
- def __init__(self, name: str, ID: int | str):
- self.name = name
- self.ID = ID
- def info_print(self):
- print(f"名字:{self.name} 工号:{self.ID}")
- def calculate_monthly_pay(self) -> float:
- """基类留接口:具体算法由子类实现。"""
- raise NotImplementedError
- class FullTimeStaff(Staff):
- def __init__(self, name: str, ID: int | str, monthly_salary: float):
- super().__init__(name, ID)
- self.monthly_salary = float(monthly_salary)
- def calculate_monthly_pay(self) -> float:
- return self.monthly_salary
- class PartTimeStaff(Staff):
- def __init__(self, name: str, ID: int | str, work_days: int | float, daily_salary: float):
- super().__init__(name, ID)
- # 入口处一次性转换为数字,后续计算就不会“字符串相乘”
- self.work_days = float(work_days)
- self.daily_salary = float(daily_salary)
- def calculate_monthly_pay(self) -> float:
- return self.daily_salary * self.work_days
- # —— 简单演示 ——
- if __name__ == "__main__":
- f = FullTimeStaff("张三", 1001, 12000)
- p = PartTimeStaff("李四", 2002, work_days=18, daily_salary=450)
- f.info_print() # 名字:张三 工号:1001
- print("全职月薪:", f.calculate_monthly_pay()) # 12000.0
- p.info_print() # 名字:李四 工号:2002
- print("兼职月薪:", p.calculate_monthly_pay()) # 8100.0
复制代码
看甲鱼老师课程(p80):
- https://www.bilibili.com/video/BV1c4411e77t
复制代码
总之小技巧
子类新增字段→自己写 __init__,并 super().__init__(...)。
类型转换放到构造函数,计算时就用“数字×数字”。
f-string 的 {} 只是插值展示,不是“在字符串里执行代码”。先算值,再插进去。 |
|