[Tutor] attribute of built-in type
spir
denis.spir at free.fr
Mon Dec 1 13:35:27 CET 2008
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
More information about the Tutor
mailing list