简体   繁体   中英

python change superclass init without changing subclass

I have a number of servers on multiple devices subclassing from SimpleXMLRPCServer and all tending to run on port 9999. However, I want to interject the interface on which to listen say

want:

server 0.0.0.0  9999

or:

server host=0.0.0.0 port=9999

got:

server (*sys.argv[:1])

and then the server picks the wrong interface on which to listen because of ordering, or dual-homing because the base-class is 'too smart'.

The base class produces an IP by selecting one from those available on a local host. How can I specify the IP and not break backward compatility for all the subclasses?

typically each server will accept a port, always seems to be 9999. And then hunt through interfacelist to pick one that is no 127.0.0.1.

Suggestion: if an arg is a number assume its a port. If its an IP assume its a host.

class Server(SimpleXMLRPCServer):
    def __init__(self, port=1234):
        host = get_ip()
        SimpleXMLRPCServer.__init__(self,addr=(host, port)) 

This feels like a strange compromise, because it reverses the args of the subclasses of SimpleXMLRPCServer:

class Server(SimpleXMLRPCServer):
    def __init__(self, port, host=None):
        if host is None:
            host = get_ip()
        SimpleXMLRPCServer.__init__(self,addr=(host, port)) 

if the change affects all the 4 subclasses I would be disappointed, the customers wont know there was a change, but dual homing will now perhaps work with the class being started with an extra argument instead of potluck.

the subclasses all do this:

class Server(SimpleXMPLRPCServer):
    def __init__(self, port=1234):
       host = get_ip()
       SimpleXMLRPCServer.__init__(self,(host, port)) 

and the main() invocation is: Server(*sys,argv[:1])

I'm not sure I understand what you're trying to do, but let me take a stab at this.

First, SimpleXMLRPCServer 's constructor takes a (host, port) pair as its addr parameter. So, your subclasses are going to have to look like this:

class Server(SimpleXMLRPCServer):
    def __init__(self, *whatever):
        # host, port = something
        SimpleXMLRPCServer.__init__(self, (host, port)) 

There's no way around that.

If you're just looking to avoid writing the if host is None bit on each subclass, just interpose an intermediate class:

class BaseServer(SimpleXMLRPCServer):
    def __init__(self, port=1234, host=None):
        if host is None:
            host = get_ip()
        SimpleXMLRPCServer.__init__(self, (host, port))

And now, each of your subclasses can be written the way (I think) you want:

class FirstServer(BaseServer):
    def __init__(self, port=1234, host=None):
        # any other initialization you need to do
        BaseServer.__init__(self, port, host)

class SecondServer(BaseServer):
    # no extra initialization at all needed for this subclass

Of course you could do that by monkeypatching SimpleXMLRPCServer.__init__ to change its interface… by why? That's just going to lead to confusion, as anyone reading your code (including you, 6 months from now) is going to have to figure out why SimpleXMLRPCServer isn't acting the way the docs say it should be. You get the same benefits out of the intermediate class, without any of the problems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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