una resueltos privados poo otra orientado objetos objeto llamar ejercicios dentro definir curso como codigo clases clase atributos python oop object attributes

resueltos - Atributos de objeto de Python: metodología de acceso



llamar una clase dentro de otra clase python (7)

Editar: ¿Puede profundizar en las mejores prácticas de nomenclatura de atributos con un subrayado inicial simple o doble? Veo en la mayoría de los módulos que se usa un único guión bajo.

El guión bajo único no significa nada especial para Python, es solo una buena práctica decir "oye, probablemente no quieras acceder a esto a menos que sepas lo que estás haciendo". Sin embargo, el guión bajo doble hace que python modifique el nombre internamente haciéndolo accesible solo desde la clase donde está definido.

El doble guion y el guion bajo final __add__ una función especial, como __add__ que se llama cuando se usa el operador +.

Lea más en PEP 8 , especialmente la sección "Convenciones de nombres".

Supongamos que tengo una clase con algunos atributos. ¿Cuál es el mejor sentido (en Pythonic-OOP) para acceder a estos atributos? Al igual que obj.attr ? ¿O tal vez escriba accessors? ¿Cuáles son los estilos de nombres aceptados para tales cosas?

Editar: ¿Puede profundizar en las mejores prácticas de nomenclatura de atributos con un subrayado inicial simple o doble? Veo en la mayoría de los módulos que se usa un único guión bajo.

Si esta pregunta ya se ha planteado (y tengo la corazonada de que sí, aunque la búsqueda no arrojó resultados), indíquelo y cerraré esta.


Algunas personas usan getters y setters. Según el estilo de codificación que use, puede ponerle nombre getSpam y seteggs. Pero también puede hacer que los atributos sean de solo lectura o solo asignar. Eso es un poco incómodo de hacer. Una forma es anular el

> __getattr__

y

> __setattr__

métodos.

Editar:

Si bien mi respuesta sigue siendo cierta, no es correcta, como me di cuenta. Hay mejores formas de crear accesadores en python y no son muy incómodas.


Con respecto a los guiones bajos simples y dobles: ambos indican el mismo concepto de ''privacidad''. Es decir, la gente sabrá que el atributo (ya sea un método o un atributo de datos ''normal'' o cualquier otra cosa) no es parte de la API pública del objeto. La gente sabrá que tocarlo directamente es invitar al desastre.

Además de eso, los atributos de doble guión bajo (pero no los atributos de guión bajo del líder único) tienen un nombre desquiciado para hacer que acceder a ellos por accidente desde subclases o en cualquier otro lugar fuera de la clase actual sea menos probable. Aún puedes acceder a ellos, pero no de forma tan trivial. Por ejemplo:

>>> class ClassA: ... def __init__(self): ... self._single = "Single" ... self.__double = "Double" ... def getSingle(self): ... return self._single ... def getDouble(self): ... return self.__double ... >>> class ClassB(ClassA): ... def getSingle_B(self): ... return self._single ... def getDouble_B(self): ... return self.__double ... >>> a = ClassA() >>> b = ClassB()

Ahora puede acceder trivialmente a._single y b._single y obtener el atributo _single creado por ClassA :

>>> a._single, b._single (''Single'', ''Single'') >>> a.getSingle(), b.getSingle(), b.getSingle_B() (''Single'', ''Single'', ''Single'')

Pero intentar acceder al atributo __double en la instancia a o b directamente no funcionará:

>>> a.__double Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: ClassA instance has no attribute ''__double'' >>> b.__double Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: ClassB instance has no attribute ''__double''

Y aunque los métodos definidos en ClassA pueden obtenerlo directamente (cuando se llama en cualquier instancia):

>>> a.getDouble(), b.getDouble() (''Double'', ''Double'')

Los métodos definidos en ClassB no pueden:

>>> b.getDouble_B() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in getDouble_B AttributeError: ClassB instance has no attribute ''_ClassB__double''

Y justo en ese error se obtiene una pista sobre lo que está sucediendo. El nombre de atributo __double , cuando se accede dentro de una clase, está siendo desmenuzado para incluir el nombre de la clase a la que se está accediendo. Cuando ClassA intenta acceder a self.__double , en realidad se convierte, en tiempo de compilación, en un acceso de self._ClassA__double , e igualmente para ClassB . (Si un método en ClassB fuera a asignar a __double , no incluido en el código por brevedad, no debería tocar el ClassA de __double sino crear un nuevo atributo.) No hay otra protección de este atributo, por lo que aún puede acceder directamente si conoce el nombre correcto:

>>> a._ClassA__double, b._ClassA__double (''Double'', ''Double'')

¿Por qué es esto un problema?

Bueno, es un problema cada vez que quiera heredar y cambiar el comportamiento de cualquier código que trate con este atributo. O bien tiene que volver a implementar todo lo que toca directamente este atributo de doble subrayado, o tiene que adivinar el nombre de la clase y modificar el nombre manualmente. El problema empeora cuando este atributo de doble guión bajo es en realidad un método: anular el método o llamar al método en una subclase significa hacer el cambio de nombre manualmente o volver a implementar todo el código que llama al método para no usar el doble subrayado . Sin mencionar el acceso al atributo dinámicamente, con getattr() : también tendrá que getattr() manualmente allí.

Por otro lado, como el atributo se reescribe trivialmente, solo ofrece una "protección" superficial. Cualquier fragmento de código aún puede obtener el atributo manualmente, aunque eso hará que su código dependa del nombre de su clase, y los esfuerzos de su parte para refactorizar su código o cambiar el nombre de su clase (manteniendo al mismo tiempo el mismo usuario visible name, una práctica común en Python) rompería innecesariamente su código. También pueden "engañar" a Python para que haga un cambio de nombre al nombrar a su clase de la misma manera que la suya: observe cómo no se incluye el nombre del módulo en el nombre del atributo mutilado. Y, por último, el atributo de doble subrayado aún es visible en todas las listas de atributos y en todas las formas de introspección que no tienen cuidado de omitir los atributos comenzando con un subrayado ( único ).

Por lo tanto, si usa nombres de subrayado doble, úselos con moderación, ya que pueden resultar bastante inconvenientes, y nunca los use para métodos o cualquier otra cosa que una subclase pueda querer volver a implementar, anular o acceder directamente . Y tenga en cuenta que el doble encabezado subrayado nombre-mangling no ofrece una protección real . Al final, usar un único guion bajo principal te gana tanto y te da menos dolor (potencial, futuro). Use un único guion bajo inicial.


Creo que la mayoría solo accede a ellos directamente, sin necesidad de métodos get / set.

>>> class myclass: ... x = ''hello'' ... >>> >>> class_inst = myclass() >>> class_inst.x ''hello'' >>> class_inst.x = ''world'' >>> class_inst.x ''world''

Por cierto, puede usar la función dir () para ver qué atributos / métodos están conectados a su instancia:

>>> dir(class_inst) [''__doc__'', ''__module__'', ''x'']

Dos barras inferiores principales, "__" se usan para hacer que un atributo o función sea privado. Para otras convenciones, remítase a PEP 08: http://www.python.org/dev/peps/pep-0008/


La forma generalmente aceptada de hacer cosas es simplemente usar atributos simples, como por ejemplo

>>> class MyClass: ... myAttribute = 0 ... >>> c = MyClass() >>> c.myAttribute 0 >>> c.myAttribute = 1 >>> c.myAttribute 1

Si encuentra que necesita poder escribir getters y setters, entonces lo que quiere buscar es "propiedades de clase de python" y el artículo de Ryan Tomayko sobre Getters / Setters / Fuxors es un excelente lugar para comenzar (aunque sea un poco largo)


No hay ningún punto real de hacer getter / setters en python, no puedes proteger cosas de todos modos y si necesitas ejecutar algún código extra al obtener / configurar la propiedad mira la propiedad () builtin (python -c ''help (property) ) '')


Python no necesita definir accesores desde el principio, ya que la conversión de atributos en propiedades es rápida e indolora. Vea lo siguiente para una demostración vívida:

Recuperación de la adicción