txt texto sobreescribir leer lectura dat como columnas archivos archivo abrir python properties python-2.7 private readonly

texto - leer columnas de un archivo en python



Propiedad de solo lectura Python (8)

Aquí hay un enfoque ligeramente diferente a las propiedades de solo lectura, que quizás deberían llamarse propiedades de escritura única, ya que tienen que inicializarse, ¿no? Para los paranoicos entre nosotros que se preocupan por poder modificar propiedades accediendo directamente al diccionario del objeto, he introducido el cambio de nombre "extremo":

from uuid import uuid4 class Read_Only_Property: def __init__(self, name): self.name = name self.dict_name = uuid4().hex self.initialized = False def __get__(self, instance, cls): if instance is None: return self else: return instance.__dict__[self.dict_name] def __set__(self, instance, value): if self.initialized: raise AttributeError("Attempt to modify read-only property ''%s''." % self.name) instance.__dict__[self.dict_name] = value self.initialized = True class Point: x = Read_Only_Property(''x'') y = Read_Only_Property(''y'') def __init__(self, x, y): self.x = x self.y = y if __name__ == ''__main__'': try: p = Point(2, 3) print(p.x, p.y) p.x = 9 except Exception as e: print(e)

No sé cuándo el atributo debe ser privado y si debería usar la propiedad.

Recientemente leí que setters y getters no son pitónicos y debería usar el decorador de propiedades. Está bien.

Pero, ¿qué ocurre si tengo un atributo que no debe configurarse desde fuera de la clase, pero puede leerse (atributo de solo lectura)? ¿Debería este atributo ser privado, y por privado quiero decir con un guión bajo, como ese self._x ? Si es así, ¿cómo puedo leerlo sin usar getter? El único método que sé ahora es escribir

@property def x(self): return self._x

De esa forma puedo leer el atributo por obj.x pero no puedo configurarlo como obj.x = 1 así que está bien.

Pero, ¿debería realmente preocuparme por configurar el objeto que no debe configurarse? Tal vez debería dejarlo. Pero, de nuevo, no puedo usar guiones bajos porque leer obj._x es extraño para el usuario, así que debería usar obj.x y, de nuevo, el usuario no sabe que no debe establecer este atributo.

¿Cuál es su opinión y práctica?


Aquí hay una manera de evitar la suposición de que

todos los usuarios aceptan adultos y, por lo tanto, son responsables de usar las cosas correctamente.

por favor mira mi actualización a continuación

Usar @property , es muy detallado, por ejemplo:

class AClassWithManyAttributes: ''''''refactored to properties'''''' def __init__(a, b, c, d, e ...) self._a = a self._b = b self._c = c self.d = d self.e = e @property def a(self): return self._a @property def b(self): return self._b @property def b(self): return self._c # you get this ... it''s long

Utilizando

Sin subrayado: es una variable pública.
Un guión bajo: es una variable protegida.
Dos guiones bajos: es una variable privada.

Excepto el último, es una convención. Todavía puede, si realmente lo intenta, acceder a las variables con doble guion bajo.

¿Asi que que hacemos? ¿Nos damos por vencidos al leer solo propiedades en Python?

¡Ay, decorador de read_only_properties al rescate!

@read_only_properties(''readonly'', ''forbidden'') class MyClass(object): def __init__(self, a, b, c): self.readonly = a self.forbidden = b self.ok = c m = MyClass(1, 2, 3) m.ok = 4 # we can re-assign a value to m.ok # read only access to m.readonly is OK print(m.ok, m.readonly) print("This worked...") # this will explode, and raise AttributeError m.forbidden = 4

Usted pregunta:

¿De read_only_properties viene read_only_properties ?

Me alegro de que haya preguntado, aquí está la fuente de read_only_properties :

def read_only_properties(*attrs): def class_rebuilder(cls): "The class decorator" class NewClass(cls): "This is the overwritten class" def __setattr__(self, name, value): if name not in attrs: pass elif name not in self.__dict__: pass else: raise AttributeError("Can''t modify {}".format(name)) super().__setattr__(name, value) return NewClass return class_rebuilder

actualizar

Nunca esperé que esta respuesta recibiera tanta atención. Sorprendentemente lo hace. Esto me animó a crear un paquete que puedes usar.

$ pip install read-only-properties

en tu shell de python:

In [1]: from rop import read_only_properties In [2]: @read_only_properties(''a'') ...: class Foo: ...: def __init__(self, a, b): ...: self.a = a ...: self.b = b ...: In [3]: f=Foo(''explodes'', ''ok-to-overwrite'') In [4]: f.b = 5 In [5]: f.a = ''boom'' --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-5-a5226072b3b4> in <module>() ----> 1 f.a = ''boom'' /home/oznt/.virtualenvs/tracker/lib/python3.5/site-packages/rop.py in __setattr__(self, name, value) 116 pass 117 else: --> 118 raise AttributeError("Can''t touch {}".format(name)) 119 120 super().__setattr__(name, value) AttributeError: Can''t touch a


Aunque me gusta el decorador de clases de Oz123, también puedes hacer lo siguiente, que usa un contenedor de clases explícito y __new__ con un método Factory de clase que devuelve la clase dentro de un cierre:

class B(object): def __new__(cls, val): return cls.factory(val) @classmethod def factory(cls, val): private = {''var'': ''test''} class InnerB(object): def __init__(self): self.variable = val pass @property def var(self): return private[''var''] return InnerB()


En general, los programas de Python deben escribirse con la suposición de que todos los usuarios son adultos que dan su consentimiento, y por lo tanto son responsables de usar las cosas correctamente. Sin embargo, en el raro caso en que simplemente no tiene sentido que un atributo sea configurable (como un valor derivado, o un valor leído de un origen de datos estático), generalmente la propiedad de getter es el patrón preferido.


Esa es mi solución.

@property def language(self): return self._language @language.setter def language(self, value): # WORKAROUND to get a "getter-only" behavior # set the value only if the attribute does not exist try: if self.language == value: pass print("WARNING: Cannot set attribute /'language/'.") except AttributeError: self._language = value


Sé que vuelvo de este hilo a la muerte, pero estaba buscando cómo hacer que una propiedad sea solo de lectura y, después de encontrar este tema, no estaba satisfecho con las soluciones ya compartidas.

Entonces, volviendo a la pregunta inicial, si comienzas con este código:

@property def x(self): return self._x

Y si quieres hacer X de manera solo, puedes agregar:

@x.setter def x(self, value): raise Exception("Member readonly")

Luego, si ejecuta lo siguiente:

print (x) # Will print whatever X value is x = 3 # Will raise exception "Member readonly"


Solo mis dos centavos, Silas Ray está en el camino correcto, sin embargo, me apetecía agregar un ejemplo. ;-)

Python es un lenguaje no seguro y por lo tanto siempre tendrá que confiar en los usuarios de su código para usar el código como una persona razonable (sensible).

Por PEP 8 :

Utilice un guion bajo principal solo para métodos no públicos y variables de instancia.

Para tener una propiedad de ''solo lectura'' en una clase, puede hacer uso de la decoración @property , necesitará heredar de un object cuando lo haga para utilizar las clases de estilo nuevo.

Ejemplo:

>>> class A(object): ... def __init__(self, a): ... self._a = a ... ... @property ... def a(self): ... return self._a ... >>> a = A(''test'') >>> a.a ''test'' >>> a.a = ''pleh'' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: can''t set attribute


Tenga en cuenta que los métodos de instancia también son atributos (de la clase) y que puede establecerlos en el nivel de clase o instancia si realmente desea ser un rudo. O que puede establecer una variable de clase (que también es un atributo de la clase), donde las útiles propiedades de solo lectura no funcionarán perfectamente. Lo que trato de decir es que el problema del "atributo de solo lectura" es, de hecho, más general de lo que generalmente se cree. Afortunadamente, existen expectativas convencionales en el trabajo que son tan fuertes que nos ciegan en estos otros casos (después de todo, casi todo es un atributo de algún tipo en Python).

Sobre la base de estas expectativas, creo que el enfoque más general y ligero es adoptar la convención de que los atributos "públicos" (sin subrayado inicial) son de solo lectura, excepto cuando se documentan explícitamente como escribibles. Esto subsume la expectativa habitual de que los métodos no serán parcheados y las variables de clase que indican los valores predeterminados de la instancia son mucho mejor. Si se siente realmente paranoico acerca de algún atributo especial, use un descriptor de solo lectura como última medida de recursos.