Python 从员工字典打印员工对象信息
我试图从雇员对象字典中打印雇员对象信息,而不使用for循环。以下是我迄今为止所做的工作:Python 从员工字典打印员工对象信息,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我试图从雇员对象字典中打印雇员对象信息,而不使用for循环。以下是我迄今为止所做的工作: employee_dict = {} class Employee: def __init__(self, id, salary): self.id = id self.salary = salary self.employee_dictionary(self) def info(self): return "Employee ID:{} \nSalary:{}
employee_dict = {}
class Employee:
def __init__(self, id, salary):
self.id = id
self.salary = salary
self.employee_dictionary(self)
def info(self):
return "Employee ID:{} \nSalary:{}".format(self.id, self.salary)
def employee_dictionary(self):
employee_dict = {self.id: self}
emp = Employee(1, 10)
emp1 = Employee(2, 5)
employee = employee_dict[1]
print(employee.info())
有人能给我指出正确的方向吗?我觉得我很亲近。此代码给我的错误是:
Traceback (most recent call last):
File "/home/rob/PycharmProjects/untitled4/sdfghsfdgjrtyrty.py", line 19, in <module>
employee = employee_dict[1]
KeyError: 1
回溯(最近一次呼叫最后一次):
文件“/home/rob/PycharmProjects/untitled4/sdfghsfdgjrtyrty.py”,第19行,在
employee=employee_dict[1]
关键错误:1
这是一个范围问题employee_dict={}
的行为与您想象的不一样
您没有在正确的范围内赋值。因此,您从未实际向其添加员工。这会导致键错误
在您的案例中,您所寻找的可能是使用一个类变量
class Employee:
employee_dict = {}
def __init__(self, id, salary):
self.id = id
self.salary = salary
self.employee_dictonary(self)
def info(self):
return "Employee ID:{} \nSalary:{}".format(self.id, self.salary)
@classmethod
def employee_dictonary(cls,current_employee):
cls.employee_dict[current_employee.id]=current_employee
emp = Employee(1, 10)
emp1 = Employee(2, 5)
print(Employee.employee_dict[1].info())
基本上,为了便于解释,您正在创建一个employee\u dict
,它将在employee的所有实例中共享
还有,你必须记住的最后一件事是,如果有人像这样创造了两名员工
emp = Employee(1, 10)
emp2 = Employee(1, 100)
调用print(Employee.Employee\u dict[1].info())
将输出
Employee ID:1
Salary:100
这可能是您想要的,但仍然认为强调员工可以被覆盖是相关的。您应该将员工定义为全局:
def employee_dictonary(self):
global employee_dict
如果没有全局关键字,则指定给局部变量
第二个问题是使用employee_dict={self.id:self}
分配给employee_dict
。这样,每次调用都会覆盖变量。该行应该是employee\u dict[self.id]=self
通过该更改,输出为:
Employee ID:1
Salary:10
在大多数情况下,强烈反对使用全局变量,请参阅。这里的根本问题是您没有正确使用字典。您不是将新员工添加到现有的全局员工目录中,而是尝试将该全局目录替换为新目录,仅包含新员工:
def employee_dictionary(self):
employee_dict = {self.id: self}
如果你解决了这个问题,你实际上要问的问题甚至不会出现:
def employee_dictionary(self):
employee_dict[self.id] = self
这将在dict中添加一个从self.id
到self
的新映射。因此,在您的两个Employee
构造之后,使用id 1和id 2,您将在dict中得到两个条目,用于键1
和2
,一切都将正常工作
也应该至少考虑一下另外两个变化:
- 用class属性替换全局变量,也可能用class方法替换
employee\u dictionary
方法,如中所述
- 将方法从
employee\u dictionary
重命名为(a)标记为private(按惯例以\u
开头的方法是private的,这意味着您的用户知道他们不应该调用它,除非他们有一个奇怪的用例),以及(b)更能反映它的功能。可能是\u寄存器
或\u添加到dict
第一个问题(同样,在scharette的回答中有详细说明)也会使你所问的问题消失。(但您仍然需要主修复程序。)
但您可能想了解更直接的范围问题,以及当您无法解决它时如何解决它
在Python中,在函数中指定的任何名称都是局部变量。如果函数中的任何地方都有一个spam=…
(或者一个带有鸡蛋作为spam:
或者其他类型的东西,当然也算是赋值),那么该函数中对spam
的每一个引用都指向该本地。因此,employee_dict={self.id:self}
创建一个名为employee_dict
的局部变量,给它赋值,然后返回,此时所有的局部变量都消失了。它恰好与全局名称相同,这一事实对Python来说并不意味着什么(尽管对于像您这样的人类读者来说,这显然令人困惑)
您使用的任何名称都是局部变量、封闭变量、全局变量或内置变量,而不在任何位置为其赋值。当您执行employee_dict[self.id]
时,因为任何地方都没有employee_dict=…
,Python会搜索本地、封闭、全局和内置作用域,以查找您所指的employee_dict
,并找到全局
您可以强制Python将名称视为全局变量,即使您为其赋值,也可以在函数顶部使用global
语句:
def employee_dictionary(self):
global employee_dict
employee_dict = {self.id: self}
添加global
是安全的,即使名称已经是全局名称。这通常是毫无意义的,但如果您不确定某个内容是否算作赋值(或者只是不确定代码的未来读者是否会确定…),并且您希望明确该变量是全局变量,则可以声明它:
def employee_dictionary(self):
global employee_dict
employee_dict[self.id] = self
你在这个问题上的缩进正确吗?如中所示,它表示您正在使用什么?您几乎肯定希望在这里使用的是employee_dict[self.id]=self
,而不是employee_dict={self.id:self}
。您希望将此员工添加到字典中,而不是将字典替换为仅处理此员工的字典,对吗?如果是这样,那就意味着你的另一个问题,即与局部变量和全局变量相关的问题,不会首先出现,因此你不需要解决它。使用global
来解决这个问题并不是一个很强的建议,事实上,无论函数是否缩进为类主体的一部分,它都不能解决这个问题。你可以在本地测试。是的,它现在可以工作了。您最初的回答中没有employee_dict[self.id]=self
。编辑后,这会产生误导。一旦您将employee_dict={self.id:self}修改为employee_dict[self.id]=self,OP就不再将其声明为全局,也不再使用