Anonymous class inheritance

I am creating a python automation API around a device configuration that looks like this:

root@EX4200-24T# show interfaces ge-0/0/6 
mtu 9216;
unit 0 {
    family ethernet-switching {
        port-mode trunk;
        vlan {
            members [ v100 v101 v102 ];
        }
    }
}

root@EX4200-24T#

I define python classes for specific actions (e.g. SET), as well as classes for keywords for an action ... The idea is that SET will go through the keyword classes and attach the class objects to the interfaces.

The problem is that the configuration of this device is rather hierarchical ... for example, if there are many instances ethernet-switching, I do not want API users to use:

# Note that each keyword corresponds to a python class that is appended
# to an InterfaceList object behind the scenes...
SET(Interface='ge-0/0/6.0', Family='ethernet-switching', PortMode='trunk', 
    Vlan=['v100', 'v101', 'v102'])
SET(Interface='ge-0/0/7.0', Family='ethernet-switching', PortMode='trunk', 
    Vlan=['v100', 'v101', 'v102'])
SET(Interface='ge-0/0/8.0', Family='ethernet-switching', PortMode='trunk', 
    Vlan=['v100', 'v101', 'v102'])

Instead, I would like to be able to use:

Family('ethernet-switching')
SET(Interface='ge-0/0/6.0', PortMode='trunk', Vlan=['v100', 'v101', 'v102'])
SET(Interface='ge-0/0/7.0', PortMode='trunk', Vlan=['v100', 'v101', 'v102'])
SET(Interface='ge-0/0/8.0', PortMode='trunk', Vlan=['v100', 'v101', 'v102'])
Family(None)
# API usage continues...

However, I cannot figure out a way to code this in python without resorting to something like this ...

f = Family('ethernet-switching')
f.SET(Interface='ge-0/0/6.0', PortMode='trunk', 
    Vlan=['v100', 'v101', 'v102'])
f.SET(Interface='ge-0/0/7.0', PortMode='trunk', 
    Vlan=['v100', 'v101', 'v102'])
f.SET(Interface='ge-0/0/8.0', PortMode='trunk', 
    Vlan=['v100', 'v101', 'v102'])

, SET() ... ...

PREFERRED API

# Note: there could be many combinations of classes to inherit from
Family('ethernet-switching')
PortMode('trunk')
SET(Interface='ge-0/0/6.0', Vlan=['v100', 'v101', 'v102'])
SET(Interface='ge-0/0/7.0', Vlan=['v100', 'v101', 'v102'])
PortMode('access')
SET(Interface='ge-0/0/8.0', Vlan=['v100'])
SET(Interface='ge-0/0/9.0', Vlan=['v100'])
Family(None)
PortMode(None)

API, ? , , ?

+5
3

?

from functools import partial
S=partial(SET, Family='ethernet-switching', PortMode='trunk')
S(Interface='ge-0/0/6.0', Vlan=['v100', 'v101', 'v102'])
S(Interface='ge-0/0/7.0', Vlan=['v100', 'v101', 'v102'])
S(Interface='ge-0/0/8.0', Vlan=['v100', 'v101', 'v102'])
+10

gnibbler functools.partial , , , decimal.getcontext(), decimal.setcontext() decimal.localcontext().

: http://docs.python.org/py3k/library/decimal : http://hg.python.org/cpython/file/default/Lib/decimal.py#l435

+2

Well, this is similar to jQuerythe select and filter APIs where they use function chains:

some_set_of_data
    .filter(first_criteria)
        .filter(second_criteria)

They also introduced a method end()that allows you to do such things:

some_set_of_data
    .filter(first_criteria)
        .filter(second_criteria)
            .do_something()
        .end()
        .do_something_else()

Note that in this example, it do_something()is called for data filtered both first_criteria, and second_criteria, but it do_something_else()is called only for data filtered only first_criteria.

Simply copying this approach in Python, which has a lot in common with JavaScript.

+1
source

All Articles