Private data

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sun Mar 18 08:06:34 EDT 2007


On Sat, 17 Mar 2007 09:31:01 -0700, Dustan wrote:

> http://dustangroups.googlepages.com/privateattributesinpython
> 
> This is something that I just threw together this morning, after a
> eureka moment. It's a way of creating private class attributes and
> static function variables (I'm not 100% sure if that's the correct
> terminology, but you get what I mean). I haven't tried to create
> private instance attributes, mainly because it would just be too
> difficult, and it would be awful syntax. I'm not considering actually
> using this, but I do have a couple questions about it.
> 
> 1. Has anyone else ever come up with something like this? I can't
> imagine I'm the only person who's ever thought of this.

I've never seen anything like this before, but then I haven't gone looking
for anything like this.



> 2. Is it possible to hack into something like this? ie, would it be
> possible to see and change these variables from client code (assuming
> the data manager has been properly removed from sight, as shown on the
> last line of class block TestPrivateClassAttributes)?

Yes.

First, an example of the code in action.

>>> import PrivateAttributes
>>> obj = PrivateAttributes.TestPrivateClassAttributes()
>>> obj.getNumInstances()
1
>>> another = PrivateAttributes.TestPrivateClassAttributes()
>>> obj.getNumInstances()
2
>>> athird = PrivateAttributes.TestPrivateClassAttributes()
>>> athird.getNumInstances()
3

The getNumInstances method reports the number of instances of the
PrivateAttributes class. There's no obvious class attribute where this
count is being kept:

>>> obj.__class__.__dict__.keys()
['__module__', 'getNumInstances', '__dict__', '__weakref__', '__doc__',
'__init__']


Here's how to hack it, and make it report wrong numbers.

>>> c = obj.getNumInstances.func_closure
>>> c[1].cell_contents.numInstances = -300
>>> 
>>> athird.getNumInstances()
-300
>>> afourth = PrivateAttributes.TestPrivateClassAttributes()
>>> athird.getNumInstances()
-299

So yes, it is absolutely hackable.

Now, I'm hardly a Python guru, but in about fifteen minutes I followed the
trail through the object chain, and found how to hack this. An real guru
would probably do it in three minutes.

I was helped a bit by having the source code. But even without the source
code, I reckon I could have done it in an hour or so, if I was motivated
enough. All the tools you need are a Python interactive session, the dir()
function and the dis module.



-- 
Steven




More information about the Python-list mailing list