[Python-Dev] Object customization (was: Arbitrary attributes on funcs and methods)

Gordon McMillan gmcm@hypernet.com
Thu, 13 Apr 2000 13:11:14 -0400


Vladimir Marangozov wrote:
> 
> 
> Obviously, the user-attr proposal is not so "simple" as it looks like.

This is not obvious to me. Both the concept and 
implementation appear fairly simple to me. 
 
> I wish we all realize what's really going on here.
> 
> In all cited use cases for this proposal, functions are no more
> perceived as functions per se, but as data structures (objects)
> which are the target of the computation. IOW, functions are just
> considered as *instances* of a class (inheriting from the builtin
> "PyFunction" class) with user-attributes, having a state, and
> eventually a set of operations bound to them.

I don't see why they aren't still functions. Putting a rack on my 
bicycle doesn't make it a pickup truck. I think it's a real 
stretch to say they would become "instances of a class". 
There's no inheritance, and the "state" isn't visible inside the 
function (probably unfortunately <wink>). Just like today, they 
are objects of type PyFunction, and they get called the same 
old way. You'll be able to hang extra stuff off them, just like 
today you can hang extra stuff off a module object without the 
module's knowledge or cooperation.
 
> I guess that everybody realized that with this proposal, one could
> bind not only doc strings, but also functions to the function.
> 
> def func(): pass
> def serialize(): ...
> func.pack = serialize
> func.pack()
> 
> What is this? This is manual instance customization.

What is "def"? What is f.__doc__ = ... ?

> Since nobody said that this would be done 'exceptionally', but rather
> on a regular basis for all functions (and generally, for all objects)
> in a program, the way to customize instances after the fact, makes
> those instances singletons of user-defined classes.

Only according to a very loose definition of "instance" and 
"user-defined class". More accurately, they are objects as 
they always have been (oops, Barry screwed up the time-
machine again; please adjust the tenses of the above).
 
> You may say "so what?". Well, this is fine if it were part of the
> object model from the start. And there's no reason why only functions
> and methods can have this functionality. Stick the __dict__ slot in
> the object header and let me bind user-attributes to all objects.

Perceived need is part of this.
 
> I have a favorite number, 7, so I want to label it Vlad's number.
> seven = 7; seven.fanclub = ['Vlad']. I want to add a boolean func
> to all numbers, n.is_prime(). I want to have a s.zip() method for a
> set of strings in my particular application, not only the builtin ones.
> 
> Why is it not allowed to have this today? Think about it!

This is apparently a reducto ad absurdum argument. It's got 
the absurdum, but not much reducto. I prefer this one:

  Adding attributes to functions is immoral. Therefore 
  func.__doc__ is immoral and should be removed.
 
For another thing, we'll need a couple generations to argue 
about what to do with those 100 singleton int objects <wink>.

> How would you solve your app needs today? Through classes and instances.
> That's the prescribed `legal' way to do customized objects; no shortcuts.
> Saying that mucking with functions' __doc__ strings is the only way to
> implement some functionality is simply not true.

No, it's a matter of convenience. Remember, Pythonistas are 
from Yorkshire ("You had Python??... You had assembler??.. 
You had front-panel toggle switches??.. You had wire-
wrapping tools??..").
 
> In short, there's no way I can accept this proposal in its current
> state and make the distingo between functions/methods and other kinds
> of objects (including 3rd party ones). If we're to go down this road,
> treat all objects as equal citizens in this regard. None or all.

They are all first class objects already. Adding capabilities to 
one of them doesn't subtract them from any other.
 
> The object model must remain consistent. This proposal opens a breach in it.
> And not the lightest!

In any sense in which you can apply the word "consistent" to 
Python's object model, I fail to see how this makes it less so.
 
> And this is only part of the reasons why I'm still firmly -1 until P3K.
> Glad to see that Barry exposed some of the truth about it, after preserving
> our throats, i.e. he understood that we understood that he fully understood
> the power of namespaces, but eventually decided to propose a fraction of
> a significant change reserved for the next major Python release... wink
> <wink object at 80c5f30>
> >>> wink.fraction = 1e+-1
> >>> wink.fraction.precision = 1e-+1
> >>> wink.compute()
> 0.0

I don't see anything here but an argument that allowing 
attributes on function objects makes them vaguely similar to 
instance objects. To the extent that I can agree with that, I fail 
to see any harm in it.

- Gordon