OO in Python? ^^

Xavier Morel xavier.morel at masklinn.net
Sun Dec 11 13:18:23 EST 2005


Matthias Kaeppler wrote:
> Why would I want to use an attribute in Python, where I would use 
> getters and setters in Java? I know that encapsulation is actually just 
> a hack in Python (common, "hiding" an implementation detail by prefixing 
> it with the classname so you can't access it by its name anymore? Gimme 
> a break...), but is that a reason to only write white box classes? ^^
> 
> - Matthias
> 

If you've ever written non-trivial code in Java, you can't deny that 
most of the classes are littered by pages and pages of

--
protected FooClass foo;
FooClass getFoo() {
	return foo;
}
void setFoo(FooClass foo) {
	this.foo = foo;
}
--

This is more or less equivalent to a simple
--
public FooClass foo;
--
but allows you to change the implementation details of the class without 
having to bork your whole interface later.

Now, you have no reason to do this in python, you can use a regular 
"real" attribute, and if you need to change the  implementation details, 
you can remove the real attribute and replace it with a virtual 
attribute through properties without changing the class' interface.
--
 >>> class Bar(object):
	def __init__(self):
		self.foo = 5

		
 >>> bar = Bar()
 >>> bar.foo
5
 >>>
 >>> # now let's change the Bar class implementation and split foo in 
boo and far
 >>>
 >>> class Bar(object):
	def __init__(self):
		self.boo = 2
		self.far = 3
	def _getfoo(self):
		return self.boo + self.far
	foo = property(_getfoo)

	
 >>> bar = Bar()
 >>> bar.foo
5
--
And this is completely transparent for anyone using the Bar class, they 
don't give a damn about what happens inside.

You can also use it to add checks on the allowed values, for example
--
 >>> class Bar(object):
	def __init__(self):
		self._foo = 5
	def _getfoo(self):
		return self._foo
	def _setfoo(self,foo):
		if not 0 <= foo <= 10:
			raise ValueError("foo's value must be between 0 and 10 (included)")
		self._foo = foo
	foo = property(_getfoo, _setfoo)

	
 >>> bar = Bar()
 >>> bar.foo
5
 >>> bar.foo = 2
 >>> bar.foo
2
 >>> bar.foo = 20

Traceback (most recent call last):
   File "<pyshell#42>", line 1, in -toplevel-
     bar.foo = 20
   File "<pyshell#37>", line 8, in _setfoo
     raise ValueError("foo's value must be between 0 and 10 (included)")
ValueError: foo's value must be between 0 and 10 (included)
 >>>
--
or everything else you'd use Java's getters/setters for, but without 
having to over-engineer your classes and wrap everything just because 
the language doesn't allow you to change your mind if you ever realize 
you made mistakes in the previous implementations.



More information about the Python-list mailing list