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

2024-04-26 05:47:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为学校做一个项目,模拟一个工资单程序,但我遇到了一个错误。我得到的错误是 “预期类型”分类,改为“员工”。相关代码是(我在生成错误的代码周围放了***,这是Employee类下的第5个函数)

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等),以运行并返回结果。我试过换衣服 支付=分类。计算支付(自付) 到 支付=分类。计算支付(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)

Tags: nameselffieldsratedefpaytotalclassification
2条回答

我会找出你的台词Classification.compute_pay(self)

  • 分类=>;阶级分类
  • 计算薪酬=>;阶级
  • 方法self=>;这=一个雇员实例

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方法之一时设置。因此,在加载employees 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)

compute_pay不是静态函数或classmethod。因此,不应该在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()

相关问题 更多 >