简体   繁体   English

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

[英]Python “instance has no attribute” error when extending SocketServer.TCPServer

I am trying to overwrite the serve_forever method of the SocketServer.TCPServer class. 我试图覆盖SocketServer.TCPServer类的serve_forever方法。 However i am getting a AttributeError: MyServer instance has no attribute '_MyServer__is_shut_down' error. 但是我得到一个AttributeError: MyServer instance has no attribute '_MyServer__is_shut_down'错误。

__is_shut_down is implemented in the SocketServer.BaseServer class and should be initialised through __init__() of SocketServer.TCPServer . __is_shut_downSocketServer.BaseServer类中实现,应该通过SocketServer.TCPServer __init__()初始化。 What am i missing? 我错过了什么?

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

By definition, a variable starting with two underscores is 'private' to a given class. 根据定义,以两个下划线开头的变量对于给定的类是“私有的”。 In reality, this means Python mangles the variable name by adding an underscore, followed by the defining class name, followed by the actual variable name. 实际上,这意味着Python通过添加下划线,后跟定义的类名,后跟实际的变量名来破坏变量名。

So __is_shut_down , being defined in SocketServer.BaseServer , is actually called _BaseServer__is_shut_down . 所以__is_shut_down ,在被定义SocketServer.BaseServer ,实际上是所谓_BaseServer__is_shut_down

Whether you should actually use it is another question, as the authors of BaseServer obviously intended it not to be used. 是否应该实际使用它是另一个问题,因为BaseServer的作者显然不打算使用它。

An example: 一个例子:

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__']

Double underscored values are name mangled in the scope they are declared or referenced in. You need to reference self._BaseServer__is_shut_down (and self._BaseServer__shutdown_request for that matter) or alias the attribute from the base class scope in the derived class scope. 双重下划线的值在它们声明或引用的范围内被self._BaseServer__is_shut_down标记。您需要引用self._BaseServer__is_shut_down (以及self._BaseServer__shutdown_request )或者从派生类范围中的基类作用域中对该属性进行别名。

@isedev has a point about avoiding interacting directly with dunderscored pseudo-privates though. @isedev有一个关于避免直接与dunderscored伪私密互动的观点。 Unless you have a compelling need to instrument every single loop through the request listener, you might be better served overriding _handle_request_noblock , which will still let you instrument every request that is processed at a single point, but without having to interact directly with the server state. 除非您迫切需要通过请求侦听器检测每个循环, _handle_request_noblock最好覆盖_handle_request_noblock ,这仍然可以让您检测在单个点处理的每个请求,但不必直接与服务器状态交互。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM