3

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...

1
  • 2
    What version of Python are you using? Running the exact same code only prints things once for me. Commented Feb 15, 2012 at 6:32

4 Answers 4

3

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]:
Sign up to request clarification or add additional context in comments.

3 Comments

For what is worth, I don't get that behaviour with ipython 0.12.
@sopier: consider this as ipython bug, using python prompt would be your solution
Now I am quite curious as to why ipython would try to access that property twice when python does only once!
2

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.

6 Comments

is a single underscore used here is a must? or is it just a convention that telling 'something'??
It's just a convention that implies "private." One could still change _year directly if they wanted to, but that would be a rather silly thing to do.
I can run your code smoothly, and start to understand the purpose of this property thing. But when I remove the underscore and running the code, it goes 'maximum recursion exceeded'. Any explanation?
When you reference self.year, it fires get_year(). get_year() references self.year and self.year fires get_year(). get_year() references..... Oh dear :)
And underscore comes to the rescue?
|
2

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.

Comments

0

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.

3 Comments

Does this answer the question?
@agf: It answers the part that asks what a property is for.
@IgnacioVazquez-Abrams can you explain with simple code example...?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.