我有一个问题要问。鉴于以下代码,您能否告诉我为什么在经理(或工人)课程中为什么
self.FirstName
给出与
相同的结果self._firstName
我原以为self._firstName
无法在任何一个类(Manager / Worker)中访问,因为它在Employee类的本地,不应该在它之外访问,不是吗?
请建议。
import gc
class Employee(object):
"""Employee Base Class"""
def __init__(self, FirstName, LastName,Age, Role):
super(Employee, self).__init__()
self._firstName = FirstName
self._lastName = LastName
self._age = Age
self._role = Role
@property
def FirstName(self):
return self._firstName
@property
def Age(self):
return self._age
@property
def Role(self):
return self._role
@FirstName.setter
def FirstName(self, value):
self._firstName = value;
pass
@Role.setter
def Role(self, value):
self._role = value;
pass
class Manager(Employee):
"""Manager class"""
def __init__(self, FirstName,LastName,Age):
Employee.__init__(self,FirstName, LastName, Age, 'Manager')
# super(Manager, self).__init__()
def getParents(self):
"""Get parents of the class"""
print(gc.get_referrers(self))
pass
def ManagerInfo(self):
print("FirstName : " + self.FirstName)
print("Role : " + self.Role)
print("Age : " + str(self.Age))
class Worker(Employee):
"""docstring for Worker"""
def __init__(self, FirstName, LastName, Age):
Employee.__init__(self,FirstName, LastName, Age, 'employee')
def getParents(self):
"""Get parents of the class"""
print(gc.get_referrers(self))
pass
def WorkerInfo(self):
print("FirstName : " + self.FirstName)
print("Role : " + self.Role)
print("Age : " + str(self.Age))
pass
# manager = Employee('John','Doe' , 40, 'Manager')
# print("{0}'s age is {1} years.".format(manager.FirstName, manager.Age))
anEmp = Worker('WorkerName', 'LastName', 20)
aManager = Manager('John', 'Doe', 40)
print(anEmp.WorkerInfo())
print(anEmp.getParents())
print("----------------------------")
print(aManager.ManagerInfo())
print(aManager.getParents())
由于
答案 0 :(得分:2)
为什么
相同的结果self.FirstName
给出与self._firstName
因为您将FirstName
定义为property
返回self._firstname
。你到底想到了什么?
我原以为self._firstName不能在任何一个类(Manager / Worker)中访问,因为它是Employee类的本地
它不属于员工类本地,它是Employee
实例的属性(它没有&#t;存在于Employee
类本身中)。
并且不应该在它之外访问,不是吗?
虽然为名称添加单个下划线前缀表示实现属性(IOW不属于公共API的部分 - 相当于大多数主流语言中的受保护的),但它并不是阻止访问该属性。实际上,在Python中绝对没有执行访问限制,它是所有约定(并且最终为__pseudoprivates
名称命名)。
Python的理念是,我们都同意成年人,并且明智地不做愚蠢的事情,比如弄清楚明确标记为实现属性的内容,而不接受完全负责破解封装。
请告诉我我应该做些什么,以确保用户只能使用setter设置值,而不是通过self._firstName
没有比你实际做过的更多了。重新阅读上面的段落,我已经提到Python执行了任何类型的 NOT 强制访问限制。 self._firstname
以前面的下划线为前缀,这是告诉"这是一个实现细节而不是API的一部分,你不应该弄乱这个属性,你甚至不应该知道它存在,所以如果你打破了一些东西,那么对你来说太糟糕了,但是你自己就是这样。
所以如果以防万一,我有一些任意逻辑在设置之前操纵setter中的值,如果用户只使用self._firstName而不是self.FirstName
,则更新的值将不可用
这种情况发生的可能性实际上相当低(而且这是轻描淡写的),但理论上是的,可以发生。 但是这完全不相关,因为如果用户使用self.FirstName
而不是因为它仍然返回陈旧值,那么你会遇到同样的问题。 。