Python项目帮助(类/预期类型)



我正在为学校做一个项目,模拟一个工资单程序,但我遇到了一个错误。我得到的错误是"应为"Classification"类型,实际为"Employee"。"。相关代码是(我在生成错误的代码周围放了***,这是Employee类下的第五个函数(。

class Employee:
def __init__(self, emp_id, first_name, last_name, address, city, state, zipcode, clas = None):
self.emp_id = emp_id
self.first_name = first_name
self.last_name = last_name
self.address = address
self.city = city
self.state = state
self.zipcode = zipcode
self.classification = clas
def make_hourly(self, hourly_rate):
self.clas = Hourly(hourly_rate)
self.classification = self.clas
def make_salaried(self, salary):
self.clas = Salaried(salary)
self.classification = self.clas
def make_commissioned(self, salary, rate):
self.clas = Commissioned(rate, salary)
self.classification = self.clas
def issue_payment(self):
***pay = Classification.compute_pay(self)***
print('Mailing', pay, 'to', self.first_name, self.last_name, 'at', self.address, self.city, self.state, self.zipcode)

class Classification(ABC):
''' Interface for employee classifications '''
@abstractmethod
def compute_pay(self):
pass
class Hourly(Classification):
''' Manages timecard info. Computes pay '''
def __init__(self, hourly_rate):
self.hourly_rate = hourly_rate
self.timecards = []     # A list of floats representing hours worked
def compute_pay(self):
for i in list_of_timecards:
if i[0] == self.emp_id:
self.timecards.extend(i[1:])
total = list(map(float, self.timecards))
total = sum(total)
self.timecards.clear()
return total * self.hourly_rate
def add_timecard(self, hours):
self.timecards.append(hours)
class Salaried(Classification):
def __init__(self, salary):
self.salary = salary
def compute_pay(self):
return self.salary / 24
class Commissioned(Salaried):
def __init__(self, salary, commission_rate):
self.commission_rate = commission_rate
self.salary = salary
self.receipts = []
def add_receipt(self, amount):
self.receipts.append(amount)
def compute_pay(self):
for i in list_of_receipts:
if i[0] == self.emp_id:
self.receipts.extend(i[1:])
total = list(map(float, self.receipts))
total = sum(total)
self.receipts.clear()
return (self.salary / 24) + ((self.commission_rate / 100) * total)

我对这个问题的理解是,我需要将"employee"对象传递给"compute_pay"函数,然后该函数将其传递给相关的子类(hourly等(以运行并返回结果。我试着改变pay=Classification.counte_pay(self(到pay=Classification.conte_pay(self.clas(但是,返回错误AttributeError:Employee对象没有属性clas这毫无意义。也许是我没有正确地将员工分配到班级?它的代码是(它从CSV文件中提取,它正确地提取数据并生成类对象,我已经检查过了(

def load_employees():
f = open("employees.csv")
f.readline() # skip header line
for line in f:
fields = line.strip().split(',')
emp = Employee(*fields[:7])
if fields[7] == '3':
clas = Hourly(fields[10])  # Need to define Hourly
emp.classification = clas
elif fields[7] == '2':
clas = Commissioned(fields[8], fields[9])
emp.classification = clas
elif fields[7] == '1':
clas = Salaried(fields[8])
emp.classification = clas
employees.append(emp)

我会算出你的线路Classification.compute_pay(self):

  • 分类=>类别分类
  • compute_pay=>类
  • method self=>this=Employee实例

pass表示什么都不做,用于避免不必要的代码
每个类方法都有self作为参数,以允许引用该类的此实例。要传递一个参数(这里是您的员工(,请使用一个参数。同时实现父类的方法会覆盖此方法。每个函数compute_pay都应该有第二个参数

def compute_pay(self, employee):
# do your stuff

然后你可以在issue_payment中使用这条线

pay = self.clas.compute_pay(self)

这里有两个问题,

首先,您的Employee实例有两个属性:clasclassification。但是,在构造函数中,只设置了classification

def __init__(...
...
self.classification = clas

但是self.clas没有设置为任何值。这就是为什么您会得到错误'Employee' object has no attribute 'clas'。仅当调用make_hourlymake_salariedmake_commissioned方法之一时设置。因此,当您加载员工CSV时,而不是像在这里那样手动创建实例

clas = Hourly(fields[10])

您应该在emp实例上调用方法make_hourly,就像一样

emp.make_hourly(fields[10])

值得注意的是,fields[10]的命名非常糟糕。与其一次拆包所有字段,不如尝试在for循环中拆包:

for a, b, c, d in csv: 
...

其次,这行代码在多种方面都是错误的

pay = Classification.compute_pay(self)

CCD_ 18不是静态函数或CCD_。因此,它不应该在Classification类本身上调用,而是在Classification实例上调用。这是您在self.clas属性中存储的内容。因此,应该在self.clas:上调用compute_pay

def issue_payment(self):
pay = self.clas.compute_pay()
...

除此之外,当您从同一类中的另一个方法内部调用一个类的方法时,您永远不需要传递self参数。这是隐含的。因此,即使compute_pay是静态的或类方法,它也会被这样调用,

Classification.compute_pay()

请注意,括号内没有self。类似地,当您调用另一个非静态方法时,self永远不会作为参数传递:

def my_method(self):
self.another_method()

最新更新