Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing Python descriptors: How best to write a general validation getter-setter
    text
    copied!<p>And by best, I mean both Pythonically and with as few lines of code as possible.</p> <p>I am used to defining classes with attributes in Python like so.</p> <pre><code>class MyClass(object): def __init__(self): self.value = 5 </code></pre> <p>Often, however, I find myself needing to ensure that <code>self.value</code> can only take a specific type of value. In the past (coming from a PHP OOP background) I've done this with a getter-setter method similar to this:</p> <pre><code> def value(self, new_value = -1) if new_value == -1: return self.value if isinstance(new_value, int) and new_value &gt; -1: self.value = new_value else: raise TypeError </code></pre> <p>I then access <code>self.value</code> with <code>self.value()</code>, and set it with <code>self.value(67)</code>. Usually I'll name-mangle <code>self.value</code> to <code>self.__value</code> to discourage its direct access.</p> <p>I've recently discovered (or am in the process of discovering) descriptors. Following closely the <a href="http://martyalchin.com/2007/nov/24/python-descriptors-part-2-of-2/" rel="nofollow">excellent discussion here</a> I've written something that looks like this:</p> <pre><code>class ValidatedAttribute(object): def __init__(self, key, kind): self.key = key self.kind = kind def __get__(self, instance, owner): if self.key not in instance.__dict__: raise AttributeError, self.key return instance.__dict__[self.key] def __set__(self, instance, value): if not isinstance(value, self.kind): raise TypeError, self.kind instance.__dict__[self.key] = value class MyUsefulClass(object): a = ValidatedAttribute("a", int) </code></pre> <p>But I have a few questions!</p> <p>Firstly, what exactly is <code>MyUsefulClass().a</code>? Is it an instance of a ValidatedAttribute class somehow bound to an instance of a <code>MyUsefulClass</code> class?</p> <p>And secondly, what I'd really like is something like,</p> <pre><code>class MyUsefulClass(object): def __init__(self): self.value = Checker(int, 99) def Checker(self, kind, default): # Code for verifying that associated attribute is of type kind. </code></pre> <p>and somehow bind an attribute access to some sort of intercept method, without having to use a whole other descriptor class.</p> <p>I'm sorry if my understanding is lacking - I'm still getting to grips with new-style Python classes. Any help or pointers in the right direction would be much appreciated.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload