Python 在父函数中使用由子函数重写的值
我定义了一个基类来处理泛型内容,以及子类,它们更具体地接受哪些内容(对象类型)。但是,在调用父类中定义的函数时,将使用父变量而不是子变量。如何让Python在父函数中使用子变量 示例代码:Python 在父函数中使用由子函数重写的值,python,python-3.x,class,Python,Python 3.x,Class,我定义了一个基类来处理泛型内容,以及子类,它们更具体地接受哪些内容(对象类型)。但是,在调用父类中定义的函数时,将使用父变量而不是子变量。如何让Python在父函数中使用子变量 示例代码: class BaseField(object): __accepted_types = (object,) def __init__(self, description=""): self.content = None self.description = d
class BaseField(object):
__accepted_types = (object,)
def __init__(self, description=""):
self.content = None
self.description = description
def set(self, content):
if isinstance(content, self.__accepted_types):
print(type(content), self.__accepted_types)
print(type(self))
self.__set(content)
else:
raise ValueError("wrong type")
def __set(self, content):
pass
class StringField(BaseField):
__accepted_types = (basestring,)
def __init__(self, description=""):
super().__init__(description)
print(self.__accepted_types)
if __name__ == '__main__':
x = StringField("a test field")
x.set(3)
我希望这段代码会引发一个ValueError
(我试图将int
传递给一个只接受str
的类),但是我得到了以下结果:
(<class 'str'>,)
<class 'int'> (<class 'object'>,) <class '__main__.StringField'>
(,)
(,)
请注意,该函数正确地返回它在
“StringField”
中,但使用“BaseField”
值作为\uu接受的类型。如果我将\u accepted\u types
声明为实例变量,则行为是相同的。您是name mangling的受害者;名称在类主体和self中被损坏。接受的\u类型
get被转换为\u基本字段\u接受的\u类型
内部set
将所有出现的\u accepted\u types
更改为accepted\u types
,它就可以正常工作了
p、 s如果您确实在使用Python 3,basestring
不存在,请使用str
作为另一个答案的后续,我强烈建议您观看PyCon 2013,其中讨论了Python名称混乱范例的目的和用法
总而言之,对对象变量使用双下划线并不是保持它们“私有”的方法。事实上,Python中的私有变量不是“一件事”;当来自其他语言时,有效地使用Python需要在这个和其他主题上转变思维
名称混乱的目的是防止父类和子类落入命名空间战争的陷阱,例如,在命名空间战争中,某些子类使用属性名的目的与父类不同
如需进一步阅读,请参阅以下其他问题和答案:
你能说得更具体些吗?当在set(self,content)
方法中将self.\uu accepted\u types
更改为\uuuu accepted\u types
或accepted\u types
时,我得到名称错误:没有定义名称“\u BaseField\uu accepted\u types”
只需在任何地方删除接受的类型的“\uu”前缀。是的,正如jsbueno所指出的,将\uuu accepted\u types
更改为accepted\u types
。您陷入的陷阱是:您可能来自一种属性可以被“保护”和“特权”的语言—Python不是这样工作的。它有一个名称篡改机制,可以让基类准确地看到它定义的属性的非overiden版本-属性的“\uuuuu”前缀。你想要的东西的位置。事实上,早期的Python教程错误地将这种机制与某种形式的“受保护”属性访问相混淆,而事实并非如此。谢谢,这就解决了问题(同时也感谢在Python3中使用的/str
)。正如jsbueno所提到的,我假设_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。。。