2016-04-13 13 views
0

Burada bir nesne oluşturmak mümkün yapmak olduğunu isteriz Ne aralığındaSQLAlchemy'de içeriğe duyarlı işlevleri parametrelerle kullanabilir miyim?

class IpRange(Base): 
    __tablename__ = 'ip_range' 
    ip_range_id = Column(Integer, Sequence('ip_range_id_seq'), primary_key=True) 
    start_ip = Column(String(15)) 
    end_ip = Column(String(15)) 
    num_ips = Column(Integer) 

içinde biraz bir başlangıç ​​adresi, bitiş adresi biçiminde IP adresi aralıkları tutmak için masa ve IP'lerin rakamdır çeşitli stilleri kullanarak ve kendi alanlarını nasıl dolduracağını öğrenmek sınıfının var.

foo = IpRange(ip='192.168.0.1') 
foo = IpRange(ip='192.168.0.0/24') 
foo = IpRange(ip='192.168.0.0-192.168.0.255') 

Çeşitli IP adresi/aralığı gösterimler ayrıştırmak olabilecek bir işlevi yazmak çok zor olmaz:

def parseIp(desired_format): 
    ... stuff to parse any valid IP address/network format ... 
    if desired_format == 'start': 
     return start_ip 
    if desired_format == 'end': 
     return end_ip 
    if desired_format == 'num_ips': 
     return num_ips 

Ve ben o zaman benim Sütunlar için default yöntemi kullanmak umuyordum

class IpRange(Base): 
    __tablename__ = 'ip_range' 
    ip_range_id = Column(Integer, Sequence('ip_range_id_seq'), primary_key=True) 
    start_ip = Column(String(15), default=parseIp('start')) 
    end_ip = Column(String(15), default=parseIp('end')) 
    num_ips = Column(Integer, default=parseIp('num_ips') 

Ancak, bu geçerli SQLAlchemy sözdizimi değil: her sütun gerekli verileri almak. Belgeler, context-sensitive default columns'dan bahseder, ancak sözdizimi, parametrelerin işleve geçirilmesine izin vermez. Yani, ben default=parseIp ile işlevi çağırabilirsem bile, ne tür bir dönüş değeri aradığımı söyleyemem.

Bunu SQLAlchemy için Sütun belirtimi içinde yapmanın bir yolu var mı? Veya alternatif bir fikir olarak, parseIp'i yeni IpRange nesnesini yaratan bir yardımcı komut dosyasına dönüştürmeli ve onu arayana geri döndürmeli miyim? Şunlar gibi:

def parseIp(ipstring): 
    ... parse data ... 
    return IpRange(start_ip=parsed_start_ip, end_ip=parsed_end_ip, num_ips=parsed_num_ips) 

>>> ipobj = parseIp('192.168.0.0/24') 

cevap

0

Yapıcıyı geçersiz kılmanız yeterli. Örnek:

class IpRange(Base): 
    def __init__(self, ip=None, **kwargs): 
     if ip is not None: 
      self.start_ip, self.end_ip = my_super_awesome_cidr_parser(ip) 
     else: 
      super(IpRange, self).__init__(**kwargs) 
+0

Fantastik! Bunun nasıl çalıştığını tam olarak anlamadım (son satır özellikle gizemli), ama gerçekten işe yarıyor. Teşekkür ederim! –

+1

@GeorgeAdams Son satır, superclass'ın ('Base') yapıcısını çağırır, bu da varsayılan davranışı kullanmanıza olanak sağlar. Bu özellik, anahtar kelimeleri bağımsız değişkenlere göre ayarlar (örneğin, IpRange (start_ip =" ... ", end_ip =" ... ") '). Super() 'nin belgeleri [burada] (https://docs.python.org/2/library/functions.html#super). – univerio

+0

Sanırım anlıyorum. Yapılması gereken doğru şey (eğer "ip" belirtilmemişse), bir "IpRange" nesnesini geleneksel şekilde yaratmaktır ('foo = IpRange (start_ip = '...')'). 'IpRange' için orijinal '__init__' kullanmak zorunda olduğumuzu sanıyordum, ama bana söylediğinize göre IpRange için bir' __init__', 'Base' için yalnızca bir tane olmadığına inanıyorum. Bir başka soru - niçin "süper (IpRange)' yerine "süper (IpRange, self)" diyorsun? –

İlgili konular