Kent Johnson a écrit :

[...big snip...]

> Do you know that you can probably just assign a __name__ attribute to
> the objects? Or name, or whatever you like?
>
> In [13]: class Foo(object): pass
>    ....:
>
> In [14]: f=Foo()
>
> In [15]: f.name
> ---------------------------------------------------------------------------
> AttributeError                            Traceback (most recent call last)
>
> /Users/kent/<ipython console> in <module>()
>
> AttributeError: 'Foo' object has no attribute 'name'
>
> In [16]: f.name = 'f'
>
> In [17]: f.name
> Out[17]: 'f'
>
> This will work for custom objects that do not have a __slots__
> attribute. Perhaps you could wrap the creation of the objects in a
> function that gives them a name?

Exactly. I presently use a tool func (actually, a Classmethod) that executes this (pseudocode):
def set_names(scope):
        for name,obj in scope.__dict__.items():
                # exclude not_to_be_named objects of the scope
                if name_has_the_proper_form:
                        # 'name' attr already used for other purpose
                        obj.id = name

Which works. I will use this method if I cannot find a way to let the objects natively have __name__ attributes. Conceptually , it is not the same thing -- at least for me. That a class of objects has such an attribute may be seen as an interface characteristics (comparable to 'iterable' or 'ordered') that could be inherited. If I want a class to define/construct ordered containers, I will simply let it inherit list's interface. The facts that python sets __name__ attributes at a low level (as you explain below) and that workarounds are not satisfying, both confirm that this is a fondamental interface charasteristics, not a superficial one.

Also, I need a name format rule to distinguish to_be_named from not_to_be_named objects. This is not a big issue, as this rule has only to be followed inside a specific scope. But maybe you understand that I do not find this conceptually /satisfying/. A logical feature that should not depend on such a random detail, rather it should be a basic property. Imagine a case where you would need to give objects characteristics such as iterable or ordered (or mutable / immutable!), by implementing the proper __xxx__ methods, based on the fact that their name has this or that format. Which may happen if such characteristics could not be inherited in python.

[...smaller snip...]

>> It is an illustration of what i'm trying to do: let a class inherit from
>> 'function' so that its instances get a __name__. This wouldn't be a harmful
>> overload I guess, as these objects have a __call__ method anyway (the reason
>> why I chose 'function').
>
> I doubt this would do what you want. AFAICT the function name is
> assigned by the compiler, not by the function constructor. (That is a
> bit of oversimplification but close enough. I think the compiler
> creates a code object, passing its name to the constructor; when a
> function object is wrapped around the code object, it pulls its name
> from the code object.)

This let me play a bit further with functions. The following confirms both that __name__ is a very low-level attribute, and that it lies in the code itself:
=============================
import types ; Function = types.FunctionType

def typ(obj): return obj.__class__.__name__
def f():pass
g = f
print id(f)
print "%s: %s at %s \n" % ( g.__name__,typ(g),id(g) )

print dir(f)
cod = g.func_code
print "cod is a '%s' object\n" % typ(cod)

h = Function(cod,{})
print "%s: %s at %s \n" % ( h.__name__,typ(h),id(h) )

==>

10464752
f: function at 10464752

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
cod is a 'code' object

f: function at 10464816
==========================

g points to the same, unique, function as f. So that we can understand that g's __name__ actually is 'f'. But this shows that an object's "birthname" is somehwhat different from further name to which the object may be bound. Now, h points to brand new object (as confirmed by its id); still, its __name__ is 'f'. This attr is well carried by the code and retrieved there, but it is not an attribute of code objects (cod.__name__ does not exist). As I see it, the __name__ is somehow a third kind of name/id for objects. In fact, if 'id()' was called 'address()' instead, then __name__ could well be called __id__. I also find highly meaningful that, among built_in types, the bool, int, float, str,... series do not have a __name__. (But this is probably an off-topic subject for the python_tutor list.)

>>> Kent

Salutation,
denis


_______________________________________________
Tutor maillist  -  [email protected]
http://mail.python.org/mailman/listinfo/tutor

Reply via email to