12

Just a quick question, I'm having a little difficulty understanding where to use properties vs. where use to plain old attributes. The distinction to me is a bit blurry. Any resources on the subject would be superb, thank you!

Michael
  • 2,031
  • 6
  • 21
  • 27
  • 3
    Just use regular attributes until you find you have to do something "special" during attribute getting or setting. Then use a property. Or, if you want the attribute to be read-only. – Keith Jun 10 '12 at 10:12
  • It's strange to me how people in the Python community seem to just understand the correct answer to this question much more than people in the C# community, where they have tools that work the same way. – Karl Knechtel Jun 10 '12 at 10:43

4 Answers4

20

Properties are more flexible than attributes, since you can define functions that describe what is supposed to happen when setting, getting or deleting them. If you don't need this additional flexibility, use attributes – they are easier to declare and faster.

In languages like Java, it is usually recommended to always write getters and setters, in order to have the option to replace these functions with more complex versions in the future. This is not necessary in Python, since the client code syntax to access attributes and properties is the same, so you can always choose to use properties later on, without breaking backwards compatibilty.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • +1, but I would say quite the opposite, i.e. to me, an _attribute_ is more flexible, in the sense that it's _completely_ free, you can do whatever you want with the data, from the inside as well as from the outside ... On the other hand, a _property_ is hooked, controlled, restricted, constrained (but I agree we can see these capabilities as being a kind of _flexibility_ as well) by an encapsulation mechanism ... But I guess it means the same thing, just the way to say it which is different :-) – cedbeu Jun 10 '12 at 13:00
  • 1
    @cblab: The question was posed from the point of view of a *class implementor*. For a class implementor, properties are more flexible, since you can simulate the exact behaviour of attributes with properties. – Sven Marnach Jun 10 '12 at 13:17
  • 1
    ah, yes, true ... I must admit that I have never thought about simulating the usage of an attribute with a property ... kinda useless nope? It's like adding lines of code that have no other goal than being there :) But you are absolutely right, in this sense it can do more, so more flexibility. – cedbeu Jun 10 '12 at 13:30
16

The point is that the syntax is interchangeable. Always start with attributes. If you find you need additional calculations when accessing an attribute, replace it with a property.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 6
    This is the important bit! In other languages (*cough*Java*cough*), once you've defined something to be an attribute, you can't go back and change it later if you want more control. So you have to write all these unnecessary getters and setters so that you have the option of changing them later. In Python, you can just write plain attributes, and replace them internally with properties later without changing the external API at all! – Katriel Jun 10 '12 at 10:13
  • I don't completely agree. Sometimes one might want to _start_ with defining something to be a property. For example when you want its value to be read-only, or it's something that can be computed when needed but isn't referenced often enough to justify storing its value in each instance. – martineau Jun 10 '12 at 10:25
  • You can always change anything later in any language; it's just a question of how much work is involved. – Karl Knechtel Jun 10 '12 at 10:42
2

Properties are attributes + a posteriori encapsulation.

When you turn an attribute into a property, you just define some getter and setter that you "attach" to it, that will hook the data access. Then, you don't need to rewrite the rest of your code, the way for accessing the data is the same, whatever your attribute is a property or not.

Thanks to this very clever and powerful encapsulation mechanism, in Python you can usually go with attributes (without a priori encapsulation, so without any getter nor setter), unless you need to do special things when accessing the data.

If so, then you just can define setters and getters, only if needed, and "attach" them to the attribute, turning it into a property, without any incidence on the rest of your code (whereas in Java, the first thing you usually do when creating a field, usually private, is to create it's associated getter and setter method).

Nice page about attributes, properties and descriptors here

cedbeu
  • 1,919
  • 14
  • 24
1

In addition to what Daniel Roseman said, I often use properties when I'm wrapping something i.e. when I don't store the information myself but wrapped object does. Then properties make excellent accessors.

L0tad
  • 574
  • 3
  • 15
Kugel
  • 19,354
  • 16
  • 71
  • 103
  • Yes, in fact you can generate these automatically from the wrapped object, and then your object has all the methods and attributes of whatever you're wrapping. Very handy. – kindall Jun 10 '12 at 15:32