Getter and Setter for member variable in Python - python

I know that it is not recommended to write getter and setter for class member variables in Python. Still I need to do it because I have a complex object which internally contains a lot of objects in depth. I need to expose a property/function in container object that will get and/or set member of inner object. How can I do this in Python?
def responseoperationcode(self,operationcode=None):
if operationcode:
self.innerobject.operationcode=operationcode
else:
return self.innerobject.operationcode
Above given function can act as a getter and setter but the syntax to use it would be confusing. My requirement is that user should get its value without using parenthesis and to set values he should pass parameters. Something like this
objectname.responseoperationcode ##this should return the value
and
objectname.responseoperationcode("SUCCESS")##this should set the value
Please suggest.

Python supports properties. You can change your code to:
#property
def responseoperationcode(self):
return self.innerobject.operationcode
#responseoperationcode.setter
def responseoperationcode(self, value):
self.innerobject.operationcode = value
Now you can use the responseoperationcode function like a field, e.g.:
objectname.responseoperationcode # this returns the value
objectname.responseoperationcode = "SUCCESS" # this sets the value

Well, if you have access to the definition of the inner objects, you could write a getter method there. Then whole thing would look similar to this:
class OuterObject:
innerObject
def getInnerField(self, field=None):
if field == None:
return self.innerObject.getField()
else:
self.innerObject.setField(field)
class InnerObject:
field
def getField(self):
return self.field
def setField(self, field):
self.field = field

Related

Python Function that creates class instances

Hello i want to create a function which creates instances of a class
def make_instance(name_instance)
name_instance=puppy()
class puppy:
def __init__(self,name):
self.name =name
make_instance(cloud)
# when i pass an argument it says the variable is undefined and i use #isinstance() it return False.
Your puppy class needs to take a name value into its constructor, and you're currently not passing in anything.
Also your function doesn't return the instance at all. It simply re-assigns the instance to the variable name_instance that you pass in (losing your input). The return value of make_instance right now is None
My guess is that you want your implementation to look like the following
def make_instance(name_instance)
return puppy(name_instance)
I do want to point out though that this function isn't useful unless it does more than just create the instance, you're just adding wrapper code around the constructor

What is a "property" used for in Python?

I was editing a blog post and started to type the word property when my autocomplete suggested a completion called new Property, curious as ever I looked it up and found that this was coming from the Python autocomplete package.
I pressed it and this code appeared:
def foo():
doc = "The property."
def fget(self):
return self._
def fset(self, value):
self._ = value
def fdel(self):
del self._
return locals()
= property(**())
I typed Grape where the cursor(s) were, so I ended up with this:
def Grape():
doc = "The Grape property."
def fget(self):
return self._Grape
def fset(self, value):
self._Grape = value
def fdel(self):
del self._Grape
return locals()
Grape = property(**Grape())
By looking at the code I can see that it's creating a local variable called doc but doesn't seem to be doing anything with it.
It's also creating three functions, one which returns self._Grape another which adds a new property to self._Grape and one which deletes self._Grape.
Where did self & _Grape come from? Is this a class of some sort, like a "pseudo class"?
Where, why and how are "new Properties" used?
Your editor is providing an unusual way to create a property. Here is some information on properties.
After reading that, you'll realize that there's no need to create the getter and setter within a function. The reason the editor does it this way is to have a scope where to define the names of the getter and setter without needing unique names. IOW, the names are hidden in the function.
So, how are the objects defined in the function (fget, fset, fdel & doc) passed to the property descriptor?
Notice the function returns the result of locals. So the return value of the function is a dict with the name of the local objects as keys and the local objects as values.
Finally, regarding self, fget, fset and fdel will be executed as if they were methods of the object which has the property so self refers to that object.

Constructing from a classmethod

Suppose I am creating a class representing and object in a KV-datastore. Creating the constructor is pretty straightforward...
class KVObject:
def __init__(self, key, value, add=True):
self.key = key
self.value = value
if add == True:
kv_create(key, value)
Now, let's say I want to retrieve a KV-object... and construct a class instance from it. I figure I'll add this class method onto my DataBaseObject class.
#classmethod
def get_kv_object(cls, key):
value = kv_get(key)
cls.__init__(key, value, add=False)
... but when calling init from the class method (cls.__init__), Python asks for an argument for self!
Any ideas? Many thanks! I know this is a bit of a simple example, but it definitely applies to some more complex, interesting situations!
Edit: Thanks for the responses. I learned something helpful while researching this, which is that object.__new__ calls __init__ on an object when calling MyClass(...), effectively providing an uninitialized instance of the class to MyClass.init with the args called from within MyClass. Likewise, it makes sense to call cls(...), as suggested in your answers. Thank you.
Think about how you would create a new database object normally, it would be something like the following:
instance = DatabaseObject(key, value, add=False)
Well within your class method the first parameter (cls in this case) is just another name for DatabaseObject, so to create an instance you would do the following:
instance = cls(key, value, add=False)
#classmethod
def get_kv_object(cls, key):
value = kv_get(key)
return cls(key, value, add=False)
__init__ does not created new instances of the cls class! It's a method that's called right after the object has been created.

How to know which next attribute is requested in python

I have class with custom getter, so I have situations when I need to use my custom getter, and situations when I need to use default.
So consider following.
If I call method of object c in this way:
c.somePyClassProp
In that case I need to call custom getter, and getter will return int value, not Python object.
But if I call method on this way:
c.somePyClassProp.getAttributes()
In this case I need to use default setter, and first return need to be Python object, and then we need to call getAttributes method of returned python object (from c.somePyClassProp).
Note that somePyClassProp is actually property of class which is another Python class instance.
So, is there any way in Python on which we can know whether some other methods will be called after first method call?
No. c.someMethod is a self-contained expression; its evaluation cannot be influenced by the context in which the result will be used. If it were possible to achieve what you want, this would be the result:
x = c.someMethod
c.someMethod.getAttributes() # Works!
x.getAttributes() # AttributeError!
This would be confusing as hell.
Don't try to make c.someMethod behave differently depending on what will be done with it, and if possible, don't make c.someMethod a method call at all. People will expect c.someMethod to return a bound method object that can then be called to execute the method; just define the method the usual way and call it with c.someMethod().
You don't want to return different values based on which attribute is accessed next, you want to return an int-like object that also has the required attribute on it. To do this, we create a subclass of int that has a getAttributes() method. An instance of this class, of course, needs to know what object it is "bound" to, that is, what object its getAttributes() method should refer to, so we'll add this to the constructor.
class bound_int(int):
def __new__(cls, value, obj):
val = int.__new__(cls, value)
val.obj = obj
return val
def getAttributes(self):
return self.obj.somePyClassProp
Now in your getter for c.somePyClassProp, instead of returning an integer, you return a bound_int and pass it a reference to the object its getAttributes() method needs to know about (here I'll just have it refer to self, the object it's being returned from):
#property
def somePyClassProp(self):
return bound_int(42, self)
This way, if you use c.somePyPclassProp as an int, it acts just like any other int, because it is one, but if you want to further call getAttributes() on it, you can do that, too. It's the same value in both cases; it just has been built to fulfill both purposes. This approach can be adapted to pretty much any problem of this type.
It looks like you want two ways to get the property depending on what you want to do with it. I don't think there's any inherent Pythonic way to implement this, and you therefore need to store a variable or property name for each case. Maybe:
c.somePyClassProp
can be used in the __get__ and
c.somePyClassProp__getAttributes()
can be implemented in a more custom way inside the __getattribute__ function.
One way I've used (which is probably not the best) is to check for that exact variable name:
def __getattribute__(self, var_name):
if ('__' in var_name):
var_name, method = var_name.split('__')
return object.__getattribute__(self, var_name).__getattribute__(method)
Using object.__get__(self, var_name) uses the object class's method of getting a property directly.
You can store the contained python object as a variable and the create getters via the #property dectorator for whatever values you want. When you want to read the int, reference the property. When you want the contained object, use its variable name instead.
class SomePyClass(object):
def getInt(self):
return 1
def getAttributes(self):
return 'a b c'
class MyClass(object):
def __init__(self, py_class):
self._py_class = py_class
#property
def some_property(self):
return self._py_class.getInt()
x = MyClass(SomePyClass())
y = self.some_property
x._py_class.getAttributes()

Can't make properties work within nested methods

Im trying to create a class with some formatting options. But i can't figure out how to do it properly...
The code produced the following error:
AttributeError: 'NoneType' object has no attribute 'valuesonly'
class Testings(object):
def format_as_values_only(self,somedata):
buildstring=somedata.values()
return buildstring
def format_as_keys_only(self):
pass
def format_as_numbers(self):
pass
def get_data_method(self):
self.data= {'2_testkey':'2_testvalue',"2_testkey2":"2_testvalue2"}
#property
def valuesonly(self):
return format_as_values_only(self.data)
test=Testings()
print test.get_data_method().valuesonly
The important thing for me is to be able to get the formatters like: class.method.formatter or so...
Thanks a lot for any hints!
get_data_method has no return value, so the result of test.get_data_method() is None. That's why you're getting that exception.
If you really want to do something like test.get_data_method().valuesonly, either define the valuesonly property on Testings, and have get_data_method return self, or have get_data_method return some new object with the properties that you want defined.
You can't do things this way. Methods are just functions defined directly inside a class block. Your function is inside another function, so it's not a method. The property decorator is useless except in a class block.
But, more fundamentally, function definitions just create local names, the same as variable assignments or anything else. Your valuesonly function is not accessible at all from outside the get_data_method function, because nothing from within a function is accessible except its return value. What you have done is no different than:
def get_data_method(self):
a = 2
. . . and then expecting to be able to access the local variable a from outside the function. It won't work. When you call get_data_method(), you get the value None, because get_data_method doesn't return anything. Anything you subsequently do with the result of get_data_method() is just operating on that same None value.
If you want to access things using the syntax you describe, you will need to make get_data_method return an object that has properties like valuesonly. In other words, write another class that provides a valuesonly property, and have get_data_method return an instance of that class. A rough outline (untested):
class DataMethodGetter(object):
def __init__(self, parent):
self.parent = parent
#property
def valuesonly(self):
return format_as_values_only(self.parent.data)
class Testings(object):
# rest of class def here
def get_data_method(self):
self.data = {'blah': 'blah'}
return DataMethodGetter(self)
However, you should think about why you want to do this. It's likely to be simpler to set it up to just call valuesonly directly on the Testing object, or to pass a flag to get_data_method, doing something like get_data_method(valuesonly=True).

Categories

Resources