【问题标题】:Efficiently introspecting Python object IP address instance ownership高效内省 Python 对象 IP 地址实例所有权
【发布时间】:2011-11-20 02:05:16
【问题描述】:

在下面的代码中,我试图找到一种从 L3Address() 类中消除 self.owner 的方法...我想知道谁拥有给定 Vlan 或接口上的 IP 地址,而无需明确地把它叫出来。

是否有更好的方法来获取 IPv4 地址的所有者(可能通过自省)?

import ipaddr

class SomethingOwned(object):
    def __init__(self, owner=None):
        self._owner = owner
        # Build self.owner (the object instance that owns the subclass object)
        self._create_owner()

    def _create_owner(self):
        """
        create self.owner and ensure the subclass was called correctly
        """
        if not (self._owner is None):
            self.owner = self._owner
        else:
            raise ValueError, "%s() must be called with an 'owner' arg, which cannot be None" % self.__class__.__name__

class L3Address(SomethingOwned):
    """
    A Layer3 IP PDU address that has an owning object
    """
    def __init__(self, version=None, owner=None, addr=None, masklen=None):
        # Call SomethingOwned.__init__(owner=owner) to add an owner attribute
        super(L3Address, self).__init__(owner=owner)
        self._addr = addr
        self._masklen = masklen
        self._version = version

        # Build self._obj
        self._create_ip_object()

        self.addr = self._obj.ip
        self.netmask = self._obj.netmask
        self.masklen = self._obj.prefixlen

    def __repr__(self):
        return "<IPv%i %s/%s>" % (self._version, self.addr, self.masklen)


    def _create_ip_object(self):
        """
        create self._obj and ensure the subclass was called with the correct version
        """
        if self._version==4:
            if (self._masklen is None):
                self._obj = ipaddr.IPv4Network(self._addr)
            else:
                self._obj = ipaddr.IPv4Network("%s/%s" % (self._addr, self._masklen))
        elif self._version==6:
            if (self._masklen is None):
                self._obj = ipaddr.IPv6Network(self._addr)
            else:
                self._obj = ipaddr.IPv6Network("%s/%s" % (self._addr, self._masklen))
        else:
            raise ValueError, "Version must be 4 or 6"


class IPv4(L3Address):
    def __init__(self, **kwargs):
        ## Initialize the IPv4 network object instance
        super(IPv4, self).__init__(version=4, **kwargs)

class IPv6(L3Address):
    def __init__(self, **kwargs):
        ## Initialize the IPv6 network object instance
        super(IPv6, self).__init__(version=6, **kwargs)

class Vlan(object):
    def __init__(self, name=None, id=None, ipv4=None):
        self.id = id
        self.name = name
        if not (ipv4 is None):
            ### NOTE: I am trying to eliminate the need for the owner arg here
            self.ipv4 = IPv4(owner=self, addr=ipv4)
    def __repr__(self):
        return "Vlan %s (name: %s)" % (self.id, self.name)

class Interface(object):
    def __init__(self, id=None, ipv4=None):
        self.id = id
        self.ipv4 = None
        if not (ipv4 is None):
            ### NOTE: I am trying to eliminate the need for the owner arg here
            self.ipv4 = IPv4(owner=self, addr=ipv4)
    def __repr__(self):
        return "Interface %s" % self.id



if __name__=='__main__':
    def find_owner(ip_instance):
        print "Owner of '%s' is '%s'" % (ip_instance, ip_instance.owner)

    find_owner(Interface(id='ge-0/0/0', ipv4='1.1.1.1').ipv4)
    find_owner(Vlan(id='25', name='accounting', ipv4='1.1.1.2/25').ipv4)

执行结果

[mpenning@hotcoffee ~]$ python cisco.py 
Owner of <IPv4 1.1.1.1/32> is 'Interface ge-0/0/0'
Owner of <IPv4 1.1.1.2/25> is 'Vlan 25 (name: accounting)'
[mpenning@hotcoffee ~]$

【问题讨论】:

    标签: object python introspection


    【解决方案1】:

    您当前使用 owner 的方法可能是最干净的解决方案。

    话虽如此,如果您需要找出谁拥有 IP 地址,gc.get_referrers() 可能会有所帮助。

    【讨论】:

      【解决方案2】:

      没有办法只从L3Protocol 中删除owner 字段并在运行时神奇地确定它。您本质上要问的是“什么对象引用了这个对象?”。当然,在一般情况下这甚至没有意义,因为可能有任意数量的对象包含对 L3Protocol 实例的引用(并且每个对象甚至可以包含任意数量的对 L3Protocol 实例的引用) .

      因此,要么您必须以某种方式记录每个 L3Protocol 的所有者,要么您只需要在有更多信息的上下文中询问 L3Protocol 的所有者可用的; owner 理论上可以是一个函数,它接受 L3Protocol 和一系列潜在所有者并返回拥有 L3Protocol(或 None)的那个。如果您有一个记录所有Interfaces 和Vlans 的对象,那么将其作为该对象的方法将起作用。

      但看起来你这样做的方式几乎是我能想到的最直接的方式,只要你确保保持双向链接(所有者 -> 拥有和拥有 -> 所有者) 一致,如果它们发生变化。

      【讨论】:

        猜你喜欢
        • 2021-10-23
        • 2014-09-14
        • 2021-10-15
        • 2015-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-01
        相关资源
        最近更新 更多