从员工字典中打印员工对象信息 [英] Printing employee object information from a dictionary of employees

查看:107
本文介绍了从员工字典中打印员工对象信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从雇员对象的字典中打印雇员对象信息,而不使用for循环。到目前为止,这是我所做的事情:

  employee_dict = {} 

类员工:

def __init __(自我,id,工资):
self.id = id
self.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_dict [1]

print(employee.info())

有人能指出我正确的方向吗?我觉得我已经接近了。该代码给我的错误是:

 跟踪(最近一次通话是最后一次):
File / home / rob /pycharmProjects/untitled4/sdfghsfdgjrtyrty.py,第19行,< module>
员工= employee_dict [1]
KeyError:1


解决方案

这里的根本问题是您没有正确使用字典。而不是将新员工添加到现有的全局 employee_dict 中,而是尝试用新的替换该全局的dict,仅包含新的员工:

  def employee_dictionary(self):
employee_dict = {self.id:自我}

如果您解决了这个问题,您实际上要问的问题甚至不会出现:

  def employee_dictionary(self):
employee_dict [self.id] =自我

这将从 self.id self 在字典中。因此,在两个ID为1和2的 Employee 构造之后,您将在dict中以键 1

结束两个条目。 code>和 2 ,一切都将正常工作。






此外,您绝对应该至少考虑其他两个更改:




  • 将全局变量替换为class属性,并可能替换 employee_dictionary 方法和类方法,如 scharette的答案中所述

  • 将方法从 employee_dictionary 重命名为(a)标记为私有的方法(以 _开头的方法按照惯例是私有的,这意味着您的用户知道除非他们有一个怪异的用例,否则他们不应该调用它),并且(b)更多地反映了它的作用。也许 _register _add_to_dict



其中的第一个也会(同样,在scharette的答案中有详细说明)使您要解决的问题消失了。 (但是无论如何,您仍然需要主要的修复程序。)






但是您可能还是想了解更直接的范围问题,以及不能消失时如何解决。



在Python中,您在函数中分配的任何名称是局部变量。如果函数中的任何地方都有 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):
全局employee_dict
employee_dict = {self.id:self}

添加 global 是安全的,即使名称已经是全局名称。这通常是没有意义的,但是如果您不确定某个东西是否可以算作赋值(或者不确定将来的代码读者是否可以肯定……),并且您想弄清楚该变量是全局变量,则可以声明它:

  def employee_dictionary(self):
全球employee_dict
employee_dict [self.id] =自我


I am attempting to print employee object information from a dictionary of employee objects without using a for loop. Here is what I have done so far:

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())

Could someone point me in the right direction? I feel like I am close. The error this code gives me is:

Traceback (most recent call last):
  File "/home/rob/PycharmProjects/untitled4/sdfghsfdgjrtyrty.py", line 19, in <module>
    employee = employee_dict[1]
KeyError: 1

解决方案

The underlying problem here is that you're not using the dictionary right. Instead of adding the new employee to the existing global employee_dict, you're trying to replace that global dict with a new one, containing just the new employee:

def employee_dictionary(self):
  employee_dict = {self.id: self}

If you fix this, the problem you're actually asking about won't even come up:

def employee_dictionary(self):
  employee_dict[self.id] = self

This will add a new mapping from self.id to self in the dict. So, after your two Employee constructions, with IDs 1 and 2, you'll end up with two entries in the dict, for keys 1 and 2, and everything will just work.


Also, you should definitely at least consider two other changes:

  • Replace the global variable with a class attribute, and possibly also replace the employee_dictionary method with a class method, as detailed in scharette's answer.
  • Rename the method from employee_dictionary to something (a) marked private (methods starting with _ are private by convention, meaning your users know they aren't supposed to be calling it unless they have a weird use case), and (b) more reflective of what it does. Maybe _register or _add_to_dict?

The first one of these would also (as, again, detailed in scharette's answer) have made the problem you're asking about go away. (But you still need the main fix anyway.)


But you probably want to understand the more immediate scope problem anyway—and how to solve it when you can't just make it go away.

In Python, any name that you assign to in a function is a local variable. If there's a spam = … anywhere in the function (or a with eggs as spam: or certainly other kinds of things that also count as assignment), every reference to spam in that function is to that local. So, employee_dict = {self.id: self} creates a local variable named employee_dict, assigns a value to it, and then returns, at which point all the locals go away. The fact that it happens to have the same name as a global doesn't mean anything to Python (although to a human reader, like you, it's obviously confusing).

Any name that you use without assigning to it anywhere is a local-or-enclosing-or-global-or-builtin variable. When you do employee_dict[self.id], because there's no employee_dict = … anywhere, Python searches the local, enclosing, global, and builtin scopes to find what you meant by employee_dict, and it finds the global.

You can force Python to treat a name as a global variable, even if you assign to it, with a global statement at the top of the function:

def employee_dictionary(self):
  global employee_dict
  employee_dict = {self.id: self}

Adding global is safe even if the name would already be a global. This is usually pointless—but if you're not sure whether something counts as an assignment (or just not sure future readers of your code would be sure…), and you want to make it clear that the variable is a global, you can declare it:

def employee_dictionary(self):
  global employee_dict
  employee_dict[self.id] = self

这篇关于从员工字典中打印员工对象信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆