El 15 de diciembre de 2015, 10:26, Chema Cortes <pych...@gmail.com> escribió:
> > > El mar., 15 dic. 2015 a las 9:22, Kiko (<kikocorre...@gmail.com>) > escribió: > >> El 15 de diciembre de 2015, 4:11, Chema Cortes <pych...@gmail.com> >> escribió: >> >>> >>> >>> El lun., 14 dic. 2015 a las 22:24, Kiko (<kikocorre...@gmail.com>) >>> escribió: >>> >>>> >>>> >>>>> *import types* >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> *a = 1for attr in dir(a): if isinstance(getattr(type(a), attr), >>>>>> types.GetSetDescriptorType): print(attr)* >>>>>> Y el resultado sería: >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> *denominatorimagnumeratorreal* >>>>>> >>>>> >>>>> Vaya, acabo de cambiar *a* para que sea *complex* en lugar de *int* y >>>>> mi código de encima no me devuelve *img* y *real*, que son >>>>> descriptores de *complex*... >>>>> >>>>> :-( >>>>> >>>> >>>> Esto parece que sí funciona: >>>> >>>> *import types* >>>> *a = 1 + 2j* >>>> >>>> >>>> >>>> *for attr in dir(a): if isinstance(getattr(type(a), attr), * >>>> >>>> >>>> * (types.GetSetDescriptorType, >>>> types.MemberDescriptorType)): print(attr)* >>>> Lo anterior parece que sí funciona. No entiendo muy bien la diferencia >>>> entre GetSetDescriptor y MemberDescriptor. >>>> ¿Sería lo anterior lo adecuado para resolver el problema? >>>> >>> >>> Oficialmente, un descriptor es todo objeto con, al menos, un método >>> "__get__": >>> >>> hasattr(attr, "__get__") >>> >> >> Eso había leído, sí, y así es. Pero lo que me confunde es cuando aquí >> definen como se invocan (TL&DR, lo llaman como un atributo): >> https://docs.python.org/3.5/howto/descriptor.html#invoking-descriptors >> >> Aquí definen las *properties*, que creía que era lo que buscaba en un >> principio: >> https://docs.python.org/3.5/howto/descriptor.html#properties >> Pero algunos atributos que actúan como *properties* no son instancias de >> *property*... >> >> Lo que estoy buscando, y no me he explicado bien por desconocimiento, >> como muchas otras veces, es saber si 'algo' actúa como una *property*, >> es decir, la puedo invocar como un atributo pero no es un atributo. >> >> Por ejemplo: >> >> >> >> >> >> >> * In [1]: type(int.from_bytes)Out[1]: builtin_function_or_methodIn [2]: >> type(int.numerator)Out[2]: getset_descriptor* >> De ahí pensaría que* from_bytes* es un método (y también es un >> descriptor, como bien indicas): >> >> I >> >> >> >> *n [3]: int.to_bytes.__get__Out[3]: <method-wrapper '__get__' of >> method_descriptor object at 0x01283328>In [4]: int.numerator.__get__Out[4]: >> <method-wrapper '__get__' of getset_descriptor object at 0x012835F8>* >> >> Lo que busco es si un descriptor se puede llamar como un atributo (como >> si fuera una property). Lo siguiente me devuelve *False*: >> >> In [5]: isinstance(int.numerator, property) >> Out[5]: False >> >> In [6]: callable(int.numerator) >> Out[6]: False >> >> Lo que me indica que* numerator* no es una *property* pero tampoco en un >> atributo al uso (un atributo al uso también deviuelve *False* con las >> dos comprobaciones anteriores). >> >> Por tanto, vuelvo a mi pregunta inicial reformulada gracias a las >> indicaciones de Chema: >> >> ¿Puedo comprobar si un descriptor funciona como un atributo de clase con >> el siguiente código? >> >> >> *import types* >> *a = 1 + 2j* >> >> >> >> *for attr in dir(a): if isinstance(getattr(type(a), attr), * >> >> * (types.GetSetDescriptorType, >> types.MemberDescriptorType)): print(attr)* >> >> Es decir, ¿un descriptor que funciona como una *property*, atributo,..., >> solo puede ser instancia de* types.GetSetDescriptorType *o >> >> * types.MemberDescriptorType?* >> A ver si ahora he atinado más con la pregunta. >> >> Disculpas por el cambalache y gracias, Chema. >> > > Si has oído que python usa "duck types", este sería el caso ilustrativo. > Descriptores son todo objeto que tenga un atributo "__set__" o "__get__", > independiente de como haya sido creado. Y está implícito en el > funcionamiento de python hasta el punto de que puedes crear propiedades > como descriptores, sin derivar necesariamente desde property. Así mismo, un > "callable" es todo objeto que tenga un atributo "__call__" que, además de > incluir funciones y métodos, también son las clases que usan "__call__" > para la creación de instancias (No confundas 'descriptor' con 'callable'). > > Se ha intentado formalizar el "duck typing" mediantes clases abstractas > (ver módulo 'abc'). > > Si no te aclaras, lo mejor es que pongas algo de código de lo que quieres > y te podría dar alguna pista. > Como diría ese gran estadista, "It is very difficult, todo esto". Creo que lo anterior resume, creo, lo que quiero: ¿Puedo comprobar si un descriptor funciona como un atributo de clase o como una *property* con el siguiente código? Cuando me refiero a descriptores en mi contexto de ignorancia supina estoy refiriéndome a cosas como *int.numerator, complex.real,...* *import types* *a = 1 + 2j* *for attr in dir(a): if isinstance(getattr(type(a), attr), * * (types.GetSetDescriptorType, types.MemberDescriptorType)): print(attr)* Es decir, ¿un descriptor que funciona como una *property*, atributo,..., solo puede ser instancia de* types.GetSetDescriptorType *o* types.MemberDescriptorType?* Gracias. Saludos.
_______________________________________________ Python-es mailing list Python-es@python.org https://mail.python.org/mailman/listinfo/python-es FAQ: http://python-es-faq.wikidot.com/