Menlo 发表于 2024-3-23 07:20:58

关于class的一些细碎小问题

题目:
# 类继承练习:人力系统
# 员工分为两类:全职员工FullTimeEmployee、兼职员工PartTimeEmployee.
#-全职和兼职都有"姓名name"、"工号 id",且都能打印姓名、工号。
#-全职有"月薪monthly_salary",
# 兼职有"日薪 daily_salary"和"每月工作天数work_days"
#-全职和兼职都有"计算月薪calculate_monthly_pay"的方法,但具体计算过程不一样。

问题:
1.老师以下代码为什么不能省去? 我省去后直接写出的代码出现了什么问题?
def __init__(self, name, ID, monthly_salary):
      super().__init__(name, ID)
      self.monthly_salary=monthly_salary

2. 在老师代码 parttime_staff 类 D_salary 方法中 self.daily*self.work_days 为什么不用加float来保证是数字乘以数字,直接相乘不会出现字符串相乘的问题吗?
3. 在我的代码 parttime_staff 类 D_salary 方法中 为什么chatGPT告诉我要删除“{} ”的符号,f + {} 不是配套固定搭配使用吗?

我的代码:
"""HR Department Programming"""

class staff:
    def __init__(self, name, ID):
      self.name=name
      self.ID=ID

    def info_print(self, print_way):
      print(f"名字:{self.name} 工号:{self.ID}")

class falltime_staff(staff):
    def M_salary(self, mounthly_salary):
      print("float(self.ID)*3")
      

class parttime_staff(staff):
    def _init__(self, name, ID, work_days, daily_salary):
      super().__init__(name, staff)
      self.work_days=work_days
      self.daily_salary=daily_salary

   
    def D_salary(self, daily_salary):
      print(f"工资: float({self.work_days}) * float({daily_salary}))



没法回答我问题的老师的代码(我手动修改微量细节-比如employee改成staff-版 ———— 我尽量没变,不排除我改瘸可能):
.
"""HR Department Programming"""

class staff:
    def __init__(self, name, ID):
      self.name=name
      self.ID=ID

    def info_print(self, print_way):
      print(f"名字:{self.name} 工号:{self.ID}")

class falltime_staff(staff):
    def __init__(self, name, ID, monthly_salary):
      super().__init__(name, ID)
      self.monthly_salary=monthly_salary
   
    def M_salary(self):
      return self.monthly_salary
      

class parttime_staff(staff):
    def _init__(self, name, ID, work_days, daily_salary):
      super().__init__(name, staff)
      self.work_days=work_days
      self.daily_salary=daily_salary

   
    def D_salary(self, daily_salary):
      return self.daily*self.work_days



FishC 发表于 2024-3-23 07:21:10

回答:

1. 不能省去的原因是,子类(fulltime_staff)继承了父类(staff)的构造函数__init__,如果不调用super().__init__(name, ID),则父类的初始化过程就会被忽略,父类的属性name和ID就无法初始化,导致后续代码出错。你遇到问题的原因是因为在parttime_staff类的构造函数中你误将staff写成了self。正确的代码应该是:
def __init__(self, name, ID, work_days, daily_salary):
    super().__init__(name, ID)
    self.work_days=work_days
    self.daily_salary=daily_salary
2. 在老师的代码中,self.daily*self.work_days是两个已经被赋值的整数,直接相乘不会出现字符串相乘的问题,所以不需要加float来保证是数字乘以数字。
3. 在你的代码中,chatGPT可能是误解了你的意思。f + {} 是配套固定搭配使用的,这里的{}表示占位符,需要填充具体的值。正确的代码应该是:
def D_salary(self, daily_salary):
    print(f"工资: {float(self.work_days) * float(daily_salary)}")
注意:在parttime_staff类的构造函数和D_salary方法中,daily_salary都不需要再传入参数,因为它们已经在构造函数中被赋值了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

集如4 发表于 2025-9-25 20:11:05


回答:

1. 不能省去的原因是,子类(fulltime_staff)继承了父类(staff)的构造函数__init__,如果不调用super().__init__(name, ID),则父类的初始化过程就会被忽略,父类的属性name和ID就无法初始化,导致后续代码出错。你遇到问题的原因是因为在parttime_staff类的构造函数中你误将staff写成了self。正确的代码应该是:
def __init__(self, name, ID, work_days, daily_salary):
    super().__init__(name, ID)
    self.work_days=work_days
    self.daily_salary=daily_salary
复制代码

2. 在老师的代码中,self.daily*self.work_days是两个已经被赋值的整数,直接相乘不会出现字符串相乘的问题,所以不需要加float来保证是数字乘以数字。
3. 在你的代码中,chatGPT可能是误解了你的意思。f + {} 是配套固定搭配使用的,这里的{}表示占位符,需要填充具体的值。正确的代码应该是:
def D_salary(self, daily_salary):
    print(f"工资: {float(self.work_days) * float(daily_salary)}")
复制代码

注意:在parttime_staff类的构造函数和D_salary方法中,daily_salary都不需要再传入参数,因为它们已经在构造函数中被赋值了。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问

不二如是 发表于 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 的 {} 只是插值展示,不是“在字符串里执行代码”。先算值,再插进去。
页: [1]
查看完整版本: 关于class的一些细碎小问题