2

I'm hoping to get some clarification here(New to python). So I'm trying to call out a large VLAN, then break that VLAN into a few smaller subnets based on some criteria.

In looking at all the class methods I see a method called _prefixlen. Looking at other posts in stackoverflow, it looks like generally the _methods are generally private module methods, and are not brought in when calling import. Source here. However, using this method it does allow me to change the prefixlen.

import ipaddress as ip
network1 = ip.ip_network(network_allocation)
network1._prefixlen = 10
print(network1.prefixlen)
>>> 10

Is this a normal convention, or did I just confused by a normal convention, any guidance would be really helpful.

Gates
  • 117
  • 2
  • 13
  • 2
    I can't find that example code in the current docs? – snakecharmerb Apr 06 '19 at 15:45
  • @snakecharmerb good call, I linked the wrong doc page, editing my link above. – Gates Apr 06 '19 at 15:49
  • 1
    `netaddr` is a third party package that you need to [install](https://netaddr.readthedocs.io/en/latest/installation.html), its `IPAddress` class is not the same as that in the stdlib. – snakecharmerb Apr 06 '19 at 15:52
  • @snakecharmerb ah, that makes way more sense. – Gates Apr 06 '19 at 15:56
  • Modified my question to be focused on the _method versus the syntax component. – Gates Apr 06 '19 at 15:58
  • 1
    Possible duplicate of [What is the meaning of a single and a double underscore before an object name?](https://stackoverflow.com/questions/1301346/what-is-the-meaning-of-a-single-and-a-double-underscore-before-an-object-name) – mkrieger1 Apr 06 '19 at 16:27
  • 1
    You aren't supposed to change the prefix length; it's an immutable property of the network that `network1` represents. If you have a different prefix length, you have a different network. – chepner Apr 07 '19 at 16:07

1 Answers1

2

Nothing is truly "private" in Python; the saying goes that "it's cultural." Something prefixed with a single underscore is "quasi-private" in that it's the developer's way of saying, "you shouldn't really need to touch this." (Or maybe, that if you rely on this in application code, it's subject to change with zero notice.)

The pattern the question seems to be getting at looks like this:

@property
def prefixlen(self):
    return self._prefixlen

Where:

  • _prefixlen is an attribute
  • prefixlen is a property - basically an instance method that you don't need to call with (), to oversimplify things

In this case, this effectively makes prefixlen readonly, though the underlying attribute _prefixlen is perfectly modifiable if you really want to:

>>> import ipaddress
>>> nw = ipaddress.ip_network('192.0.2.0/24')
>>> nw.prefixlen
24
>>> nw.prefixlen = 32
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

If you want to modify the prefix, you might as well create a new object -- Adding a @property.setter that modifies the given object inplace would fundamentally change what you're looking at, so IPv4Network and IPv6Network instances are best treated as being immutable.

One nice trick is that the class constructors accept a tuple for the address parameter, so you can construct from parts:

>>> ipaddress.IPv4Network((nw.network_address, 32))
IPv4Network('192.0.2.0/32')

Thanks to @chepner for this last trick from his comments below.

Brad Solomon
  • 38,521
  • 31
  • 149
  • 235
  • 2
    There's no setter because the length of a prefix isn't *supposed* to be changed. `192.0.2.0/24` and `192.0.2.0/26`, for example, are two different prefixes. – chepner Apr 07 '19 at 15:19
  • 1
    Instances of `IPv4Network` (and other similar classes in the module) are immutable in spirt, if not in fact. If you have `192.0.2.0/24` and want `192.0.2.0/26`, you get a new instance with `IPv4Network((nw.network_address, 26))`. – chepner Apr 07 '19 at 15:45
  • 3
    "you shouldn't really need to touch this." I'd say "unless we know each other personally, don't expect a warning if I get rid of this method in the future" – sleblanc Apr 07 '19 at 15:52
  • Super helpful guys. I think some of my confusion is coming from understanding of methods, attributes, properties and the like. I'll go dive into this more. – Gates Apr 07 '19 at 18:02