Python setter does not change variable - python-2.7

May be I do not completely understand the concept of properties in python, but I am confused by the behaviour of my Python program.
I have a class like this:
class MyClass():
def __init__(self, value):
self._value = value
#property
def value(self):
return self._value
#value.setter
def value(self, value):
self._value = value
What I would expect is, that calling MyClass.value = ... changes the content of _value. But what actually happened is this:
my_class = MyClass(1)
assert my_class.value == 1 # true
assert my_class._value == 1 # true
my_class.value = 2
assert my_class.value == 2 # true
assert my_class._value == 2 # false! _value is still 1
Did I make a mistake while writing the properties or is this really the correct behaviour? I know that I should not call my_class._value for reading the value, but nevertheless I would expect that it should work, anyway. I am using Python 2.7.

The class should inherit object class (in other word, the class should be new-style class) to use value.setter. Otherwise setter method is not called.
class MyClass(object):
^^^^^^

Related

How to use patterns in the definition of a variable in Django [duplicate]

How do you set/get the values of attributes of t given by x?
class Test:
def __init__(self):
self.attr1 = 1
self.attr2 = 2
t = Test()
x = "attr1"
There are built-in functions called getattr and setattr
getattr(object, attrname)
setattr(object, attrname, value)
In this case
x = getattr(t, 'attr1')
setattr(t, 'attr1', 21)
If you want to keep the logic hidden inside the class, you may prefer to use a generalized getter method like so:
class Test:
def __init__(self):
self.attr1 = 1
self.attr2 = 2
def get(self,varname):
return getattr(self,varname)
t = Test()
x = "attr1"
print ("Attribute value of {0} is {1}".format(x, t.get(x)))
Outputs:
Attribute value of attr1 is 1
Another apporach that could hide it even better would be using the magic method __getattribute__, but I kept getting an endless loop which I was unable to resolve when trying to get retrieve the attribute value inside that method.
Also note that you can alternatively use vars(). In the above example, you could exchange getattr(self,varname) by return vars(self)[varname], but getattrmight be preferable according to the answer to What is the difference between vars and setattr?.
Note: This answer is very outdated. It applies to Python 2 using the new module that was deprecated in 2008.
There is python built in functions setattr and getattr. Which can used to set and get the attribute of an class.
A brief example:
>>> from new import classobj
>>> obj = classobj('Test', (object,), {'attr1': int, 'attr2': int}) # Just created a class
>>> setattr(obj, 'attr1', 10)
>>> setattr(obj, 'attr2', 20)
>>> getattr(obj, 'attr1')
10
>>> getattr(obj, 'attr2')
20

Can I use a dictionary to call methods from different classes that inheritate from the same class?

I have two classes that inherit from the same base class, and they have some common methods (in fact, properties). I will need to do this:
input: an int and an object from either class;
output: the result of one of the methods (determined by the int) of the corresponding class.
I think I can use a dictionary to do this, as the following code:
class ChangeInt(object):
def bar(self, i):
print(i)
class PlusOne(ChangeInt):
def bar(self, i):
print(i+1)
class PlusTwo(ChangeInt):
def bar(self, i):
print(i+2)
methods_dict = {0:ChangeInt.bar}
print(methods_dict[0](PlusOne(), 0))
print(methods_dict[0](PlusTwo(), 0))
I expect the output to be 1,2, but I actually get this:
0
None
0
None
I would like to know how these results are generated and what should I do to fix it up. Thanks in advance.
I totally mess up the format in the comment, so I'll paste it here.
thanks to Ryan Haining in Dynamic Method Call In Python 2.7 using strings of method names, I've found another way to do this:
class ChangeInt(object):
def bar(self, i):
print(i)
class PlusOne(ChangeInt):
def bar(self, i):
print(i+1)
class PlusTwo(ChangeInt):
def bar(self, i):
print(i+2)
methods_dict = {0:'bar'}
getattr(PlusOne(), methods_dict[0])(0)
getattr(PlusTwo(), methods_dict[0])(0)
This may not be the best way to do it, but it produces the expected result:
class ChangeInt(object):
def bar(self, i):
if not ('ChangeInt' in str(self.__class__)):
self.bar(i)
else:
print(i)
class PlusOne(ChangeInt):
def bar(self, i):
print(i+1)
class PlusTwo(ChangeInt):
def bar(self, i):
print(i+2)
methods_dict = {0:ChangeInt.bar}
methods_dict[0](ChangeInt(), 0)
methods_dict[0](PlusOne(), 0)
methods_dict[0](PlusTwo(), 0)
and prints:
0
1
2
The bar() function in the base class calls the method associated with given self instance or the base class implementation if it's an instance of base class itself (just print(i)). This is important, without it the code will be calling self.bar(i) infinitely if you invoke it on the base class (i.e. until it reaches max allowable recursion call number).
The check if not ('ChangeInt' in str(self.__class__)): is necessary since issubclass will return True for the parent class too,
issubclass(class, classinfo)
Return true if class is a subclass
(direct, indirect or virtual) of classinfo. A class is considered a
subclass of itself. classinfo may be a tuple of class objects, in
which case every entry in classinfo will be checked. In any other
case, a TypeError exception is raised.
And the point is to distinguish between the base/parent class and any subclasses.
Finally, since your function calls don't return anything explicitly, they actually return None. That None is what you are printing when enclosing the calls in an additional print,
print(methods_dict[0](PlusOne(), 0))
I removed the extra print so you only print the (assuming) intended content.

how to check if a variable is of type enum in python

I have an enum like this
#enum.unique
class TransactionTypes(enum.IntEnum):
authorisation = 1
balance_adjustment = 2
chargeback = 3
auth_reversal = 4
Now i am assigning a variable with this enum like this
a = TransactionTypes
I want to check for the type of 'a' and do something if its an enum and something else, if its not an enum
I tried something like this
if type(a) == enum:
print "do enum related stuff"
else:
print "do something else"
The problem is it is not working fine.
Now i am assigning a variable with this enum like this
a = TransactionTypes
I hope you aren't, because what you just assigned to a is the entire enumeration, not one of its members (such as TransactionTypes.chargeback) If that is really what you wanted to do, then the correct test would be:
if issubclass(a, enum.Enum)
However, if you actually meant something like:
a = TransactionTypes.authorisation
then the test you need is:
# for any Enum member
if isinstance(a, Enum):
or
# for a TransactionTypes Enum
if isinstance(a, TransactionTypes):
reliable solution:
from enum import IntEnum
from collections import Iterable
def is_IntEnum(obj):
try:
return isinstance(obj, Iterable) and isinstance (next(iter(obj)), IntEnum)
except:
return False # Handle StopIteration, if obj has no elements
I thought I`ve got a ugly way. eg:
print(o.__class__.__class__)
Output:
<enum.EnumMeta>
as mentioned use isinstance method to check weather an instance is of enum.Enum type or not.
A small working code for demonstration of its usage:
import enum
class STATUS(enum.Enum):
FINISHED = enum.auto()
DELETED = enum.auto()
CANCELLED = enum.auto()
PENDING = enum.auto()
if __name__ == "__main__":
instance = STATUS.CANCELLED
if isinstance(instance, enum.Enum):
print('name : ', instance.name, ' value : ', instance.value)
else:
print(str(instance))
Output:
name : CANCELLED value : 3
There are already good answers here but in case of it might be useful for some people out there
I wanted to stretch the question a little further and created a simple example
to propose a humble solution to help caller function who does maybe little knowledge about Enum
solve problem of sending arguments to functions that take only Enum
as a parameter by proposing a converter just below the file that Enum was created.
from enum import Enum
from typing import Union
class Polygon(Enum):
triangle: 3
quadrilateral: 4
pentagon: 5
hexagon: 6
heptagon: 7
octagon: 8
nonagon: 9
decagon: 10
def display(polygon: Polygon):
print(f"{polygon.name} : {polygon.value} ")
def do_something_with_polygon(polygon: Polygon):
"""This one is not flexible cause it only accepts a Polygon Enum it does not convert"""
""" if parameter is really a Polygon Enum we are ready to do stuff or We get error """
display(polygon)
def do_something_with_polygon_more_flexible(maybe_polygon_maybe_not: Union[Polygon, int, str]):
""" it will be more convenient function by taking extra parameters and converting"""
if isinstance(maybe_polygon_maybe_not, Enum):
real_polygon = maybe_polygon_maybe_not
else:
real_polygon = get_enum_with_value(int(maybe_polygon_maybe_not), Polygon, Polygon.quadrilateral)
""" now we are ready to do stuff """
display(real_polygon)
def get_enum_with_value(key: int, enum_: any, default_value: Enum):
""" this function will convert int value to Enum that corresponds checking parameter key """
# create a dict with all values and name of Enum
dict_temp = {x.value: x for x in
enum_} # { 3 : Polygon.triangle , 4 :Polygon.quadrilateral , 5 : Polygon.pentagon , ... }
# if key exists for example 6 or '6' that comes to do_something_with_polygon_more_flexible
# returns Polygon.hexagon
enum_value = dict_temp.get(key, None)
# if key does not exist we get None
if not enum_value:
... # if key does not exist we return default value (Polygon.quadrilateral)
enum_value = default_value # Polygon.quadrilateral
return enum_value

In python 2.7, how can I wrap a class instance method or decorate it with a try/except block?

I have a repeating set of lengthy try/except1/except2/etc blocks in a series of class methods that only differ by the outside class method being called on an outside class instance. Below is a simplified version (there are actually 4 exceptions that I am handling and eight methods that only differ by the instance method being called):
class MyClass(object):
def __init__(self):
self.arg = 'foo'
def method1(self, arg1):
err = -1
y = None
try:
x = AnOutsideClass(self.arg) # Creates a class instance of an imported class
y = x.outsideclassmethod1(arg1) # Calls an instance method that returns another different class instance
except MyException1:
x.dosomething() # Needed to handle error
except MyException2:
err = 0
finally:
del x
return y, err
def method2(self, arg1, arg2, arg3):
err = -1
y = None
try:
x = AnOutsideClass(self.arg)
y = x.outsideclassmethod2(arg1, arg2, arg3) # This is the only thing changed
# A different method with different argument requirements
except MyException1:
x.dosomething()
except MyException2:
err = 0
finally:
del x
return y, err
def method3 ...
I have been trying various ways of condensing this code by trying to wrap the two statements in the try: portion of the code by using nested functions, decorators, etc, but seem to fail due to the fact that I am have trouble translating other examples of this due to: 1) am creating a class instance that needs to be used later in one of the except blocks and 2) am calling an instance method and 3) I need to return the result of the instance method.
Is there anyway of accomplishing this with partial from functools or descriptors or any other means? I have a clunky implementation currently with an extended if/elif block that picks the instance method based on an integer code that I use in a wrapper function, but am thinking there must be a more elegant way. I am relatively new to Python and am at a loss...
You could use a function factory (i.e., a function that returns a function).
def make_method(methname):
def method(self, *args):
err = -1
y = None
try:
x = AnOutsideClass(self.arg) # Creates a class instance of an imported class
y = getattr(x, methname)(*args) # Calls an instance method that returns another different class instance
except MyException1:
x.dosomething() # Needed to handle error
except MyException2:
err = 0
finally:
del x
return y, err
return method
class MyClass(object):
def __init__(self):
self.arg = 'foo'
method1 = make_method('outsideclassmethod1')
method2 = make_method('outsideclassmethod2')
The make_method is passed the outside method name as a string.
getattr is used (inside method) to get the actual method from x given the string methname.
getattr(x, 'foo') is equivalent to x.foo.
The * in def method(self, *args) tells Python that method can accept an arbitrary number of positional arguments.
Inside method, args is a tuple. The * in y = getattr(x, methname)(*args) tells Python to pass the elements in args as individual arguments to the method returned by getattr(x, methname). The * unpacking operator is explained in the docs, here, and also in this blog.

Extending django.forms.FloatField

I'm attempting to create a custom form field that works the same as float field for all intents and purposes, but that (by default) outputs the float value with no trailing zeros e.g. 33 rather than 33.0
I attempted to simply extend django.forms.FloatField like so:
class CustomFloatField(django.forms.FloatField):
def to_python(self, value):
"""
Returns the value without trailing zeros.
"""
value = super(django.forms.FloatField, self).to_python(value)
# code to strip trailing zeros
return stripped_value
But this ended up with me getting validation errors. When I looked closer at the FloatField class I noticed that in its own to_python() method it calls super(IntegerField, self).to_python(value) which checks to ensure the value can be cast to an int, and it was here that my code seemed to trip up. This has left me thoroughly confused. How does FloatField work at all if it has to try and cast it's value to an int? :)
Most likely I'm barking entirely up the wrong tree here but if someone could point me in the right direction I'd be grateful.
Your hunch is right - FloatField isn't really calling on the to_python method of IntegerField. To illustrate what's really going on,
class A(object):
def __init__(self):
print "A initialized"
def to_python(self, value):
print "A: to_python"
return value
class B(A):
def __init__(self):
print "B initialized"
def to_python(self, value):
value = super(B, self).to_python(value)
print "B: value = "
print int(value)
return int(value)
class C(B):
def to_python(self, value):
value = super(B, self).to_python(value)
print "C: value = "
print float(value)
return float(value)
c = C()
c.to_python(5.5)
gives the output,
B initialized
A: to_python
C: value =
5.5
To put it in context, the line in FloatField's to_python:
value = super(IntegerField, self).to_python(value)
is really calling up to Field's to_python, which is simply,
def to_python(self, value):
return value
before calling the rest of the code. This might help you further: Understanding Python super() with __init__() methods