[pyar] Consulta sonsa

22 views
Skip to first unread message

Martin Cerdeira

unread,
Mar 31, 2012, 2:11:00 PM3/31/12
to Python Argentina
Buenas, como va?

Consulta, estaba jugando un poco con metaclases y, me topé con algo que, creí que sabía pero, no :) Paso a ejemplificar:

class Foo():
  def __init__(self):
     self.bar = 'bip'

f = Foo()
print f.bar

print hasattr(Foo, 'bar')


Esto lo que hace es, imprimir por pantalla:

bip
False

Es decir, yo creí que hasattr() tenía que devolver True ahi, pero python (que tiene la razón) me dijo que no.

Cuál sería la manera correcta de preguntar por ese atributo?

Saludos y graciasss!!!

-------------------------------------
Martín Cerdeira - Software Developer
At the end of the day, ship the fucking thing! It’s great to rewrite your code and make it cleaner and by the third time it’ll actually be pretty. But that’s not the point—you’re not here to write code; you’re here to ship products. - Jamie Zawinski


Tomas Zulberti

unread,
Mar 31, 2012, 2:14:58 PM3/31/12
to Python Argentina
On Sat, Mar 31, 2012 at 3:11 PM, Martin Cerdeira
<martinc...@gmail.com> wrote:
> Buenas, como va?
>
> Consulta, estaba jugando un poco con metaclases y, me topé con algo que,
> creí que sabía pero, no :) Paso a ejemplificar:
>
> class Foo():
>   def __init__(self):
>      self.bar = 'bip'
>
> f = Foo()
> print f.bar
>
> print hasattr(Foo, 'bar')
>
>
> Esto lo que hace es, imprimir por pantalla:
>
> bip
> False
>
> Es decir, yo creí que hasattr() tenía que devolver True ahi, pero python
> (que tiene la razón) me dijo que no.
>
> Cuál sería la manera correcta de preguntar por ese atributo?


El problema esta en que vos estas preguntando por la clase y no por la
instancia.

El self.bar hace que el attributo pertenezca a una instancia. Si vos haces:
print hasattr(f, 'bar')

ahi devuelve true porque la instancia si lo tiene.

>
> Saludos y graciasss!!!
>

Saludos,
TZ
_______________________________________________
pyar mailing list py...@python.org.ar
http://listas.python.org.ar/listinfo/pyar

PyAr - Python Argentina - Sitio web: http://www.python.org.ar/

La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar

Maxi

unread,
Mar 31, 2012, 2:16:53 PM3/31/12
to Python Argentina
2012/3/31 Martin Cerdeira <martinc...@gmail.com>:

> Buenas, como va?
>
> Consulta, estaba jugando un poco con metaclases y, me topé con algo que,
> creí que sabía pero, no :) Paso a ejemplificar:
>
> class Foo():
>   def __init__(self):
>      self.bar = 'bip'
>
> f = Foo()
> print f.bar
>
> print hasattr(Foo, 'bar')
>
>
> Esto lo que hace es, imprimir por pantalla:
>
> bip
> False
>
> Es decir, yo creí que hasattr() tenía que devolver True ahi, pero python
> (que tiene la razón) me dijo que no.
>
> Cuál sería la manera correcta de preguntar por ese atributo?

En principio te diría que deberias hacer print hasattr(f, 'bar'), o
sea, el atributo bar de la *instancia* f
Ahora, ¿vos querés saber si la clase F tiene el atributo bar?

Fijate acá: http://docs.python.org/library/functions.html#hasattr


Saludos

j0hn

unread,
Mar 31, 2012, 3:11:25 PM3/31/12
to Python Argentina
On Sat, Mar 31, 2012 at 3:11 PM, Martin Cerdeira <martinc...@gmail.com> wrote:
Buenas, como va?

Consulta, estaba jugando un poco con metaclases y, me topé con algo que, creí que sabía pero, no :) Paso a ejemplificar:

class Foo():
  def __init__(self):
     self.bar = 'bip'

f = Foo()
print f.bar

print hasattr(Foo, 'bar')


Esto lo que hace es, imprimir por pantalla:

bip
False

Es decir, yo creí que hasattr() tenía que devolver True ahi, pero python (que tiene la razón) me dijo que no.

Cuál sería la manera correcta de preguntar por ese atributo?

Saludos y graciasss!!!

Para que hasattr(Foo, 'bar') de True, bar tendría que ser un atributo de clase de Foo:

>>> class Foo:
...     bar = 'bip'
... 
>>> hasattr(Foo, 'bar')
True
>>> 

pero en ese caso el atributo bar es alcanzado por todas las instancias y también sin instanciar.


Martin Cerdeira

unread,
Mar 31, 2012, 5:03:53 PM3/31/12
to Python Argentina
On Sat, Mar 31, 2012 at 3:16 PM, Maxi <maxir...@gmail.com> wrote:
Ahora, ¿vos querés saber si la clase F tiene el atributo bar?

Digamos, quiero saber si la clase tiene el atributo, independientemente de si depende o no de la instancia... No sé si se puede hacer eso.

Saludos
 

nachopro

unread,
Mar 31, 2012, 6:30:27 PM3/31/12
to Python Argentina
2012/3/31 Martin Cerdeira <martinc...@gmail.com>:

> On Sat, Mar 31, 2012 at 3:16 PM, Maxi <maxir...@gmail.com> wrote:
>>
>> Ahora, ¿vos querés saber si la clase F tiene el atributo bar?
>
>
> Digamos, quiero saber si la clase tiene el atributo, independientemente de
> si depende o no de la instancia... No sé si se puede hacer eso.
>

Mmm... a ver si esto les sirve:
http://docs.python.org/reference/datamodel.html#slots


--
ignacio benedetti a.k.a. nachopro
mailto:tran...@gmail.com
http://blog.nachopro.com.ar/

Martin Cerdeira

unread,
Apr 2, 2012, 10:18:14 PM4/2/12
to Python Argentina
On Sun, Apr 1, 2012 at 1:41 AM, Alejandro J. Cura <al...@protocultura.net> wrote:
On Sat, Mar 31, 2012 at 18:03, Martin Cerdeira <martinc...@gmail.com> wrote:
> Digamos, quiero saber si la clase tiene el atributo, independientemente de
> si depende o no de la instancia... No sé si se puede hacer eso.

Si lo tiene la clase, lo tiene la clase.
Si lo tiene la instancia, lo tiene la instancia.

La única manera de saber si lo tiene *alguna* de las instancias de la
clase, es guardar tooooodas las instancias y ver si alguna lo tiene:

>>> class F:
...     pass
...
>>> f1=F()
>>> f2=F()
>>> f3=F()
>>> f3.bar = "baz"
>>> any("bar" in vars(i) for i in [f1, f2, f3])
True


Pero me parece que si necesitás hacer eso, es que hay algo feo en el
diseño de tu código.
Porqué no contás un poco más que querés hacer?

En realidad, no quiero hacer nada. Fue algo que vi haciendo pruebas relativas a otra cosa (estaba jugando con metaclases) y, me pregunté si se podía hacer.

Saludos y gracias!

fisa

unread,
Apr 3, 2012, 12:00:37 PM4/3/12
to Python Argentina
El día 2 de abril de 2012 23:18, Martin Cerdeira
<martinc...@gmail.com> escribió:
> _______________________________________________
> pyar mailing list py...@python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de
> Argentina - http://www.usla.org.ar

La cuestión de fondo es que en realidad en python las clases no
definen los atributos que van a tener las instancias, como pasa en la
mayoría de los otros lenguajes.
La clase solo define el comportamiento (métodos de instancia) y
después lo que sea referido a la clase en sí, pero no define qué
atributos va a tener una instancia de ella.

En python los atributos son algo propio de la instancia, y por eso
varias instancias de una misma clase pueden tener atributos diferentes
entre sí. En el __init__ lo que se hace es *agregarle* los atributos
que queremos a la instancia recién creada (que recibís en el parámetro
self).
El __init__ no "define" los atributos que tienen todas instancias de
una clase, sino que "agrega" atributos a una instancia específica (la
que recién se creó). Pero esa instancia ya fue creada, ya es una
instancia de la clase *antes* de que le agreguemos todos los
atributos, porque los atributos no son algo definido por su clase.

Por eso funciona esto:

import random

class Cosa:
def __init__(self):
tipo = random.randint(0, 3)
if tipo == 1:
self.nombre = ''
self.edad = 0
elif tipo == 2:
self.ancho = 0
self.alto = 0

(notar que el tipo puede ser 0, en cuyo caso no le agregamos atributos
a la instancia)

Fijate que diferentes instancias de Cosa tendrían diferentes atributos
(incluso ninguno extra), porque el __init__ de Cosa agrega atributos
diferentes a self aleatoriamente.

Por eso, porque los atributos de las instancias *no* están definidos
en la clase, es que no podés preguntarle a la clase qué atributos van
a tener sus instancias.

Saludos!

--
fisa  -  Juan Pedro Fisanotti

nachopro

unread,
Apr 3, 2012, 12:41:18 PM4/3/12
to Python Argentina
2012/4/3 fisa <fis...@gmail.com>:

class Persona(object):
__slots__ = ('nombre', 'apellido', 'dni',)

y chau picho!
http://docs.python.org/reference/datamodel.html#slots

--
ignacio benedetti a.k.a. nachopro
mailto:tran...@gmail.com
http://blog.nachopro.com.ar/

nachopro

unread,
Apr 3, 2012, 12:53:00 PM4/3/12
to Python Argentina
2012/4/3 nachopro <tran...@gmail.com>:

>
> class Persona(object):
>    __slots__ = ('nombre', 'apellido', 'dni',)
>
> y chau picho!
> http://docs.python.org/reference/datamodel.html#slots

Hola picho! interpreté mal la consulta incialmente, y esto no sirve :(
Pero al menos, los que no lo conocían, ahora pueden gozar de slots!

Reply all
Reply to author
Forward
0 new messages