Reputation: 74
I want to ask about Python Property, I'm writing the code belows...
anyone can explain about my code's output and explain in simple way what is property for and when we should use it?
class C(object):
def __init__(self):
self.x = 'sulthan'
self.y = 'ahnaf'
@property
def name(self):
print self.x
print self.y
Now when I run the code:
>>> c = C()
>>> c.name
sulthan
ahnaf
sulthan
ahnaf
Why it prints 2 times? Sorry for the question, I'm just noob who wants to understand python OOP...
Upvotes: 3
Views: 729
Reputation: 362478
This is an %autocall bug in ipython. Related tickets on launchpad and github. It is apparently resolved in the current version of ipython.
The purpose of properties is to hide fancy logic behind what looks like ordinary attribute assignment/access. You should only do this when you have a design reason that makes it necessary, python is not java so writing boilerplate getters and setters on everything is not needed.
What Ignacio is trying to tell you is that there does not seem to be any reason why you have those print statements in the definition of name()
.
Here is a more usual implementation of your example, with properties.
class Person(object):
def __init__(self):
self._name = 'sulthan ahnaf'
@property
def name(self):
return self._name
@name.setter
def name(self, value):
self._name = value
Now you have an attribute, _name
, which you can control access to by using the "attribute" name
. Consenting adults will leave your _name
alone because it has an underscore prepended, but note that this is nothing more than a convention.
Upvotes: 2
Reputation: 2609
Properties are especially useful when you want to access attributes of an object directly and need to have some extra code around getters/setters in some cases.
Imagine you have a car object.
class Car(object):
def __init__(self, make, model, year, vin):
self.make = make
self.model = model
self.year = year
self.vin = vin
my_car = Car('Ford', 'Taurus', 2005, '123ABCVINSARELONG999')
Now imagine that I need to change the year on the car. I might do it a couple different ways.
my_car.year = 2006
my_car.year = '2007'
The second way gives me some serious problems if I'd like to assume the year is a number. See the following:
if(my_car.year > 2010):
print('Shiney new!')
The challenge is that setting attributes directly is very clean and slick, but is not providing us an opportunity to do any data validation (maybe I want to ensure the make is in a list of known makes, for example) or data type conversion (in the year example).
Properties come to the rescue by allowing us to setup wrapper code around attribute assignment and/or retrieval but not requiring that we do that for all attributes or even requiring us to know ahead of time that we want to do some extra validation. I can, after the fact, modify my Car object as follows and it would still be used in exactly the same way.
class Car(object):
def __init__(self, make, model, year, vin):
self.make = make
self.model = model
self._year = year
self.vin = vin
def get_year(self):
return self._year
def set_year(self, val):
self._year = int(val)
year = property(get_year, set_year)
You still access year as my_car.year
and you still set it with my_car.year = 2006
, but it now converts the value into an int where necessary and throws an exception if the value provided by the user doesn't convert into an int properly.
Upvotes: 2
Reputation: 14854
It seems to a problem with ipython, if you use python prompt it shows proper output (single time)
[avasal@avasal]$ python
Python 2.7 (r27:82500, Sep 16 2010, 18:02:00)
[GCC 4.5.1 20100907 (Red Hat 4.5.1-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class C(object):
... def __init__(self):
... self.x = 'sulthan'
... self.y = 'ahnaf'
... @property
... def name(self):
... print self.x
... print self.y
...
>>> c1 = C()
>>> c1.name
sulthan
ahnaf
>>>
[avasal@avasal]$ ipython
Python 2.7 (r27:82500, Sep 16 2010, 18:02:00)
Type "copyright", "credits" or "license" for more information.
IPython 0.10.2 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]: class C(object):
...: def __init__(self):
...: self.x = 'sulthan'
...: self.y = 'ahnaf'
...: @property
...: def name(self):
...: print self.x
...: print self.y
...:
In [2]: c1 = C()
In [3]: c1.name
sulthan
ahnaf
sulthan
ahnaf
In [4]:
Upvotes: 3
Reputation: 798456
You use properties when you want to be able to change how an attribute assignment or access behaves without having to change how you do it. It certainly isn't for the purpose of running random/arbitrary statements for no reason.
Upvotes: 0