why my code run wrong ,it is about '#property' - python

I used python 2.5, I want to know how can change the next code when the Platform is python2.5 or python2.6
class C(object):
def __init__(self):
self._x = None
#property
def x(self):
"""I'm the 'x' property."""
return self._x
#x.setter
def x(self, value):
self._x = value
#x.deleter
def x(self):
del self._x
a=C()
print a.x#error
thanks
thanks ,alex,i think property must be 3 arguments in your example
but ,i have seen a code which with 'property' only use 1 argumennt ,why,can it work
class SortingMiddleware(object):
def process_request(self, request):
request.__class__.field = property(get_field)
request.__class__.direction = property(get_direction)

Python 2.5 does not support the .setter and .deleter sub-decorators of property; they were introduced in Python 2.6.
To work on both releases, you can, instead, code something like:
class C(object):
def __init__(self):
self._x = None
def _get_x(self):
"""I'm the 'x' property."""
return self._x
def _set_x(self, value):
self._x = value
def _del_x(self):
del self._x
x = property(_get_x, _set_x, _del_x)

Related

A simple class of Python can kill Spyder4.1.4 (Python3.8)

On the way learning Python, I have read some class examples and tried to practice. But how can this piece of code can kill Spyder4.1.4 (Python3.8) by just running?
p=Point(101,202,0)
Kernel died, restarting...
class Point():
id=0
def __init__(self, x, y, z:float=0):
self._x = x; self._y = y; self._z = z; self.id+=1
#property
def x(self):
return self._x
#x.setter# to define a "non-public member"
def x(self, value):
self._x=value
#property
def y(self):
return self._y
#y.setter
def y(self, value):
self._y=value
#property
def xy(self):
return [self._x,self._y]
#xy.setter
def xy(self,xval,yval):
self._x=xval;self._y=yval
#property
def z(self):
return self._z
#z.setter
def z(self, value):
self._z=value
#property
def id(self):
return self.id
I have tried Jupyter notebook or https://ideone.com/hjUDTU. But none is working. I am really lost...

Python abstractclass Inheritance

I have two class structured as below
from abc import ABCMeta, abstractmethod
class C(metaclass=ABCMeta):
""""""
def __init__(self, x, y):
self._x = x
self._y = y
#property
#abstractmethod
def x(self):
"""Get the _x"""
#x.setter
#abstractmethod
def x(self, value):
"""Set the x"""
#property
def y(self):
"""Get the _y"""
#y.setter
def y(self, value):
"""Set the _y"""
class D(C):
""""""
def __init__(self, x, y):
self._x = x
self._y = y
#property
def x(self):
return self._x
#C.x.setter
def x(self, value):
self._x = value
#property
def y(self):
return self._y
#C.y.setter
def y(self, value):
self._y = value
When I initialize an instance of D. It throws a error:
TypeError: Can't instantiate abstract class D with abstract methods x
When I rewrite setters decorator in D as
#x.setter
def x(self, value):
self._x = value
it works. But in python abc document https://docs.python.org/3/library/abc.html it states:
in disappreciated #abc.abstractproperty
If only some components are abstract, only those components need to be updated to create a concrete property in a subclass:
class D(C):
#C.x.setter
def x(self, val):
...
I don't know why write in this way will lead to error. Please help me understand the logic here. Thank you.
When you write #C.x.setter above your setter, you're setting x to a version of C.x with the setter replaced with your new setter function. Only the setter - the getter you wrote earlier is discarded. You're still using C.x's abstract getter.
The example in the docs uses #C.x.setter because they want the behavior it provides. In the doc example, C.x has a concrete getter, and they just want to replace the setter. That's not the case in your code.

How do I deny private variables from reading in python?

I am trying to execute javascript code in python, using pyv8 safely. At the end of the day, I have an object being used by javascript, with few fields I would like to have hidden.
I know python doesn't have encapsulation (as explained in this question), but yet, is there a way to disable access using __getattribute__?
class Context(object):
def __init__(self, debug):
self._a = ...
self._b = ...
self._c = ...
self._unlocked = False
def __enter__(self):
self._unlocked = True
def __exit__(self, exc_type, exc_val, exc_tb):
self._unlocked = False
def __getattribute__(self, name):
if object.__getattribute__(self, "_unlocked"):
return object.__getattribute__(self, name)
if name.startswith("_"):
return None
return object.__getattribute__(self, name)
So this object denies access to a "private" variables, unless unlocked using like this:
ctx = Context()
...
with ctx:
# _b is accessible here
print ctx._b
As far as there's no way to do with from javascript, nor to call __enter__ since the object is "locked".
Seems not very efficient though. Is there a better way?
You could use a property getter that restricts access?
class Context(object):
def __init__(self):
self._x = None
#property
def x(self):
"""I'm the 'x' property."""
return "Property can not be accessed."
#x.setter
def x(self, value):
self._x = value
#x.deleter
def x(self):
del self._x
More info can be found here:
https://docs.python.org/3/library/functions.html#property

call a setter from __init__ in Python

How can I call a Python (v2.7) setter property from inside __init__? I written the following class but I dont know how to change it to make it work. I get an AttributeError: 'test' object has no attribute '_x' exception. There are a few similar questions around here but couldnt find an answer so far. The idea is when the initialiser is called to do some processing/slicing and assign the result to an attribute
class test(object):
def __init__(self, a,b):
self._x = self.x(a,b)
#property
def x(self):
return self._x
#x.setter
def x(self, a, b):
self._x = "Get this from {} and make a dataframe like {}".format(a,b)
self.x is a property, so you'd just assign directly to it like you would with a regular attribute:
def __init__(self, a, b):
self.x = (a, b)
However, the setter is given one object, always; in the above case, it is passed a tuple; you could unpack it:
#x.setter
def x(self, value):
a, b = value
self._x = "Get this from {} and make a dataframe like {}".format(a,b)
Note the value argument; that's the result of the assignment being passed to the setter.
Demo:
>>> class test(object):
... def __init__(self, a, b):
... self.x = (a, b)
... #property
... def x(self):
... return self._x
... #x.setter
... def x(self, value):
... a, b = value
... self._x = "Get this from {} and make a dataframe like {}".format(a,b)
...
>>> t = test(42, 'foo')
>>> t.x
'Get this from 42 and make a dataframe like foo'

Setting Values Of Inherited Properties

I want to be able to create a concrete instance of a class that inherits from another concrete class, which in turn inherits from an abstract class.
The basic pattern is:
from abc import ABCMeta, abstractproperty
class Foo(object):
__metaclass__ = ABCMeta
#abstractproperty
def x(self):
pass
#abstractproperty
def y(self):
pass
class Bar(Foo):
x = None
y = None
def __init__(self, x, y):
self.x = x
self.y = y
#property
def x(self):
return self.x
#x.setter
def x(self, value):
self.x = value
#property
def y(self):
return self.y
#y.setter
def y(self, value):
self.y = value
class Baz(Bar):
def __init__(self):
super().__init__(x=2, y=6)
a = Baz()
When I try to create the instance of Baz I get a RecursionError: maximum recursion depth exceeded error. (As well as a pylint warning telling me that the signatures of the setter methods don't match the signatures of the base class)
However, if I remove the setters, I get an error self.x = x AttributeError: can't set attribute
What's the correct pattern to do this?
You need to change names for your x() / y() methods or for your x / y properties, for example rename
class Bar(Foo):
x = None
y = None
To:
class Bar(Foo):
x_val = None
y_val = None
And rename the references to x / y as well.
What you did is basically:
def x():
return x()
It happened because your def x overridden the x = None, so x is a function(property) that is calling itself. Avoid this by using another attribute(named differently) for storing the actual value of x.
Example from python docs (https://docs.python.org/3.5/library/functions.html#property):
class C:
def __init__(self):
self._x = None
#property
def x(self):
return self._x
#x.setter
def x(self, value):
self._x = value
Note: attribute names starting with underscore should be considered "private" and should not be directly accessed outside of the class. But it's only a convention for programmers, technically they are just normal attributes and you can do whatever you want, but it's nice to follow some convention, isn't it?

Categories

Resources