当扩展SocketServer.TCPServer时,Python出现“实例没有属性”错误

3
我正在尝试覆盖SocketServer.TCPServer类的serve_forever方法。但是我遇到了一个错误:AttributeError: MyServer instance has no attribute '_MyServer__is_shut_down'__is_shut_downSocketServer.BaseServer类中实现,并且应该通过SocketServer.TCPServer__init__()进行初始化。我错过了什么吗?
import SocketServer

class MyServer(SocketServer.TCPServer):

    def __init__(self, server_address, RequestHandlerClass):
            SocketServer.TCPServer.__init__(self, server_address, 
                                             RequestHandlerClass)

    def serve_forever(self, poll_interval=0.5):
        self.__is_shut_down.clear()
        try:
            while not self.__shutdown_request:
                 print "SOMETHING"
                 r, w, e = _eintr_retry(select.select, [self], [], [],
                                       poll_interval)
                 if self in r:
                   self._handle_request_noblock()
        finally:
            self.__shutdown_request = False
            self.__is_shut_down.set()

尝试使用super(MyServer, self).__init__代替? - 2rs2ts
另外:你的缩进看起来很奇怪。你应该确保不要混合使用制表符和空格(使用 python -tt 运行程序),即使你一直在使用制表符,也应该切换到四个空格的缩进。 - DSM
2个回答

5

根据定义,以两个下划线开头的变量是“私有”的,只属于给定的类。实际上,这意味着Python会通过添加一个下划线、定义类名和实际变量名来篡改变量名。

因此,__is_shut_downSocketServer.BaseServer中定义,实际上被称为_BaseServer__is_shut_down

是否应该使用它是另一个问题,因为BaseServer的作者明显不希望它被使用。

一个例子:

class A(object):
    def __init__(self):
        self.__my_variable = 1

a = A()

dir(a)
['_A__my_variable',   <== mangled variable name
 '__class__',
 '__delattr__',
 '__dict__',
 '__doc__',
 '__format__',
 '__getattribute__',
 '__hash__',
 '__init__',
 '__module__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 '__weakref__']

2
双下划线的值在声明或引用它们的范围内被名称混淆。您需要引用self._BaseServer__is_shut_down(以及self._BaseServer__shutdown_request)或在派生类作用域中从基类作用域别名该属性。
@isedev提到了避免直接与dunderscored伪私有变量交互的观点。除非您有一个迫切的需要来检测每个请求侦听器中的循环,否则最好重写_handle_request_noblock,这仍然可以让您在单个点上检测处理的每个请求,但无需直接与服务器状态交互。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接