继承缺失属性
Inheritance missing attribute
我收到一条错误消息说 class 吉他没有属性 "type",但它应该继承自超级 class 设备。
class Equipment(object):
__id = 0
__type = 0
__brand = 0
__model = 0
__serialNumber = 0
__purchaseCost = 0
__hireCost = 0
__available = 0
def __init__(self, type, brand, model, serialNumber, purchaseCost, hireCost, available):
self.__type = type
self.__brand = brand
self.__model = model
self.__serialNumber = serialNumber
self.__purchaseCost = purchaseCost
self.__hireCost = hireCost
self.__available = available
def get_type(self):
return self.__type
def set_type(self,type):
self.__type = type
def get_brand(self):
return self.__brand
def set_brand(self,brand):
self.__brand = brand
def get_model(self):
return self.__brand
def set_model(self,model):
self.__model = model
def get_serialNumber(self):
return self.__serialNumber
def set_serialNumber(self,serialNumber):
self.__serialNumber = serialNumber
def get_purchaseCost(self):
return self.__purchaseCost
def set_purchaseCost(self,purchaseCost):
self.__purchaseCost = purchaseCost
def get_hireCost(self):
return self.__hireCost
def set_hireCost(self,hireCost):
self.__hireCost = hireCost
def get_available(self):
return self.__available
def set_available(self,available):
self.__available = available
def toString(self):
return "type : {}, brand : {}, model : {}, serial number : {}, purchase cost : {}, hire cost : {}, available : {}".format(self.__type,
self.__brand,
self.__model,
self.__serialNumber,
self.__purchaseCost,
self.__hireCost,
self.__available)
class Guitar(Equipment):
__subtype = 0
__bodyType = 0
__pickupType = 0
__tremSystem = 0
def __init__(self, type, brand, model, serialNumber, purchaseCost, hireCost, available, subtype, bodyType, pickupType, tremSystem):
super(Guitar, self).__init__(type, brand, model, serialNumber, purchaseCost, hireCost, available)
self.__subtype = subtype
self.__bodyType = bodyType
self.__pickupType = pickupType
self.__tremSystem = tremSystem
def get_subtype(self):
return self.__subtype
def set_subtype(self, subtype):
self.__subtype = subtype
def get_bodyType(self):
return self.__bodyType
def set_bodyType(self, bodyType):
self.__bodyType = bodyType
def get_pickupType(self):
return self.__pickupType
def set_pickupType(self, pickupType):
self.__pickupType = pickupType
def get_tremSystem(self):
return self.__tremSystem
def set_tremSystem(self, tremSystem):
self.__tremSystem = tremSystem
def toString(self):
return "type : {}, subtype : {}, brand : {}, model : {}, serial number : {}, purchase cost : {}, hire cost : {}, available : {}, body type : {}, pickup type : {}, trem system : {}".format(self.__type,
self.__subtype,
self.__brand,
self.__model,
self.__serialNumber,
self.__purchaseCost,
self.__hireCost,
self.__available,
self.__bodyType,
self.__pickupType,
self.__tremSystem)
def main():
type = input("please enter type: ")
brand = input("please enter brand: ")
model = input("please enter model: ")
serialNumber = input("please enter serial number: ")
purchaseCost = input("please enter purchase cost: ")
hireCost = input("please enter hire cost: ")
available = input("is item available: ")
if type == "guitar":
subtype = input("please enter subtype: ")
bodyType = input("please enter body type: ")
pickupType = input("please enter pickup config: ")
tremSystem = input("please enter trem system: ")
guitar = Guitar(type, brand, model, serialNumber, purchaseCost, hireCost, available, subtype, bodyType, pickupType, tremSystem)
print(guitar.toString())
main()
我对装备class也做了同样的事情,所以我认为这一定是一个继承的东西。
当你在 class 中定义一个变量时,变量前面有双下划线,最后最多有一个下划线,它会导致 python 执行 Name Mangling在定义的时候class。
就是这样的名字 - __type
被转换为 _<className>__type
。从 documentation -
Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped.
显示此行为的示例 -
>>> class CA:
... def __init__(self):
... self.__type = 1
...
>>> c = CA()
>>> c.__type
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'CA' object has no attribute '__type'
>>> c._CA__type
1
举个例子 - __type
,之后你不能使用 __type
访问 class 之外的变量,当它被继承时,它将被继承为 _<ClassName>__type
.
即使在继承期间也适用相同的规则,
>>> class BA(CA):
... pass
...
>>> b = BA()
>>> b._CA__type
1
但从表面上看,不确定您是否真的需要在类中定义所有名称,这样就会发生 名称重整。如果您不需要进行名称重整,请删除起始双下划线。
此外,当你直接在class中定义一个变量时,它们变成了class变量,即所有实例共享相同的引用,直到你将每个实例的引用设置为不同的对象(通过赋值)。在您的情况下,您不需要将所有变量都定义为 class 变量。
您在所有属性名称前加上了两个下划线。这会触发名称修改机制,将 class 名称添加到属性名称中,因此子 classes 无法覆盖它们。这是设计使然,旨在避免意外覆盖(有点像 Java 中的 "private final")
所以这里的解决方案是去掉这些下划线。 Python 没有真正的访问限制机制(更接近的是上面解释的名称修改)并且依赖于一个简单的命名约定:带有 单个 前导下划线的名称被视为 "not part of the public api"(等同于其他语言中的 "protected")所以这可能就是您想要的。
话虽这么说,你在这里甚至不需要这个。 Python 对计算属性有很强的支持,因此您也可以删除所有 getters/setters 并改用普通属性,如果需要,您可以随时选择将它们转换为计算属性。
我收到一条错误消息说 class 吉他没有属性 "type",但它应该继承自超级 class 设备。
class Equipment(object):
__id = 0
__type = 0
__brand = 0
__model = 0
__serialNumber = 0
__purchaseCost = 0
__hireCost = 0
__available = 0
def __init__(self, type, brand, model, serialNumber, purchaseCost, hireCost, available):
self.__type = type
self.__brand = brand
self.__model = model
self.__serialNumber = serialNumber
self.__purchaseCost = purchaseCost
self.__hireCost = hireCost
self.__available = available
def get_type(self):
return self.__type
def set_type(self,type):
self.__type = type
def get_brand(self):
return self.__brand
def set_brand(self,brand):
self.__brand = brand
def get_model(self):
return self.__brand
def set_model(self,model):
self.__model = model
def get_serialNumber(self):
return self.__serialNumber
def set_serialNumber(self,serialNumber):
self.__serialNumber = serialNumber
def get_purchaseCost(self):
return self.__purchaseCost
def set_purchaseCost(self,purchaseCost):
self.__purchaseCost = purchaseCost
def get_hireCost(self):
return self.__hireCost
def set_hireCost(self,hireCost):
self.__hireCost = hireCost
def get_available(self):
return self.__available
def set_available(self,available):
self.__available = available
def toString(self):
return "type : {}, brand : {}, model : {}, serial number : {}, purchase cost : {}, hire cost : {}, available : {}".format(self.__type,
self.__brand,
self.__model,
self.__serialNumber,
self.__purchaseCost,
self.__hireCost,
self.__available)
class Guitar(Equipment):
__subtype = 0
__bodyType = 0
__pickupType = 0
__tremSystem = 0
def __init__(self, type, brand, model, serialNumber, purchaseCost, hireCost, available, subtype, bodyType, pickupType, tremSystem):
super(Guitar, self).__init__(type, brand, model, serialNumber, purchaseCost, hireCost, available)
self.__subtype = subtype
self.__bodyType = bodyType
self.__pickupType = pickupType
self.__tremSystem = tremSystem
def get_subtype(self):
return self.__subtype
def set_subtype(self, subtype):
self.__subtype = subtype
def get_bodyType(self):
return self.__bodyType
def set_bodyType(self, bodyType):
self.__bodyType = bodyType
def get_pickupType(self):
return self.__pickupType
def set_pickupType(self, pickupType):
self.__pickupType = pickupType
def get_tremSystem(self):
return self.__tremSystem
def set_tremSystem(self, tremSystem):
self.__tremSystem = tremSystem
def toString(self):
return "type : {}, subtype : {}, brand : {}, model : {}, serial number : {}, purchase cost : {}, hire cost : {}, available : {}, body type : {}, pickup type : {}, trem system : {}".format(self.__type,
self.__subtype,
self.__brand,
self.__model,
self.__serialNumber,
self.__purchaseCost,
self.__hireCost,
self.__available,
self.__bodyType,
self.__pickupType,
self.__tremSystem)
def main():
type = input("please enter type: ")
brand = input("please enter brand: ")
model = input("please enter model: ")
serialNumber = input("please enter serial number: ")
purchaseCost = input("please enter purchase cost: ")
hireCost = input("please enter hire cost: ")
available = input("is item available: ")
if type == "guitar":
subtype = input("please enter subtype: ")
bodyType = input("please enter body type: ")
pickupType = input("please enter pickup config: ")
tremSystem = input("please enter trem system: ")
guitar = Guitar(type, brand, model, serialNumber, purchaseCost, hireCost, available, subtype, bodyType, pickupType, tremSystem)
print(guitar.toString())
main()
我对装备class也做了同样的事情,所以我认为这一定是一个继承的东西。
当你在 class 中定义一个变量时,变量前面有双下划线,最后最多有一个下划线,它会导致 python 执行 Name Mangling在定义的时候class。
就是这样的名字 - __type
被转换为 _<className>__type
。从 documentation -
Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped.
显示此行为的示例 -
>>> class CA:
... def __init__(self):
... self.__type = 1
...
>>> c = CA()
>>> c.__type
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'CA' object has no attribute '__type'
>>> c._CA__type
1
举个例子 - __type
,之后你不能使用 __type
访问 class 之外的变量,当它被继承时,它将被继承为 _<ClassName>__type
.
即使在继承期间也适用相同的规则,
>>> class BA(CA):
... pass
...
>>> b = BA()
>>> b._CA__type
1
但从表面上看,不确定您是否真的需要在类中定义所有名称,这样就会发生 名称重整。如果您不需要进行名称重整,请删除起始双下划线。
此外,当你直接在class中定义一个变量时,它们变成了class变量,即所有实例共享相同的引用,直到你将每个实例的引用设置为不同的对象(通过赋值)。在您的情况下,您不需要将所有变量都定义为 class 变量。
您在所有属性名称前加上了两个下划线。这会触发名称修改机制,将 class 名称添加到属性名称中,因此子 classes 无法覆盖它们。这是设计使然,旨在避免意外覆盖(有点像 Java 中的 "private final")
所以这里的解决方案是去掉这些下划线。 Python 没有真正的访问限制机制(更接近的是上面解释的名称修改)并且依赖于一个简单的命名约定:带有 单个 前导下划线的名称被视为 "not part of the public api"(等同于其他语言中的 "protected")所以这可能就是您想要的。
话虽这么说,你在这里甚至不需要这个。 Python 对计算属性有很强的支持,因此您也可以删除所有 getters/setters 并改用普通属性,如果需要,您可以随时选择将它们转换为计算属性。