[Python-Dev] PEP 3144: IP Address Manipulation Library for the Python Standard Library

"Martin v. Löwis" martin at v.loewis.de
Wed Aug 26 20:35:21 CEST 2009


>> netaddr employs a simple variant of the GoF Strategy design pattern (with
> added Python sensibility).
> 
> It would be nice if you could avoid employing this kind of acronyms without
> explaining them. Not everybody drinks the design pattern kool-aid.
> (Google tells me that GoF seems to mean "Gang of Four", which is of course as
> meaningful as a hip-hop band name can be :-))
> 
> In any case, if you think netaddr's implementation strategy is better than
> ipaddr's, a detailed comparison would be welcome.

Just in case it still isn't clear "Strategy" above doesn't refer to
"implementation strategy" (i.e. "way of implementing things").

Instead, "Strategy" is a specific design pattern, originally defined by
one of Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides.

See

http://en.wikipedia.org/wiki/Strategy_pattern

for a detailed description. The basic idea is that you can switch
algorithms at run-time, by merely replacing one object with another.

To use it, you define an abstract base class with a method called
"execute". You then create as many subclasses as you want, redefining
"execute" to provide specific *strategies*. You create a (often global)
variable pointing to one instance of the base class, and dynamically
assign this variable with an instance of the appropriate strategy
class. Users of the strategy don't need to know what strategy is chosen.

The wikipedia article points (IMO correctly) out that the Strategy
pattern is mostly useless in languages that have true function pointers,
such as Python. You can still have the global variable part, but you
don't need the abstract base class part at all.

In the specific case of netaddr, I think David is referring to the
netaddr.strategy package, which has modules called ipv4 and ipv6,
both implementing functions like valid_str and str_to_arpa.
Then, class IPAddress has a method reverse_dns, which is defined
as

    def reverse_dns(self):
        """The reverse DNS lookup record for this IP address"""
        return self._module.int_to_arpa(self._value)

So IPv4 addresses and IPv6 addresses share the same class, but instances
have different values of _module. IPAddress.__init__ looks at the
version keyword parameter if given, otherwise, it tries str_to_int
first for v4, then for v6.

Whether that's better or not than using subclasses, I don't know.

Regards,
Martin


More information about the Python-Dev mailing list