On 5/20/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > which is the better way to calculate the value of attributes of a class ? > for example: > > (A) > def cal_attr(self, args): > #do some calculations > self.attr = calculated_value > and then if the vlue of attribute is needed, > self.cal_attr(args) > some_var = self.attr > or I can define cal_attr() as follows: > (B) > def cal_attr(self, args): > #do some calculations > return calculated_value > and then, if the value of attribute is needed, > self.attr = self.cal_attr(args) > some_var = self.attr
The way, I get it: you are trying to *cache* the value of an *expensive* calculation. You should worry about it if only if: a. It is *really* expensive to calculate the value. b. The value is read more often then it can change. Otherwise, just don't bother with it (i.e.use some_var = obj.cal_value(*args) ). But if you really want to cache the value, maybe you should keep track if the value is valid: class C(object): def calc_attr(self, *args): """Calculates value of "attr". """ self._attr = calculated_value self._attr_valid = True def get_attr(self, *args): """Use this to get values.""" self._attr_valid or self.calc_attr(*args) return self._attr def another_method(self, *args): """Does some calculations which invalidate *cached* value of "attr". """ # do something self._attr_valid = False > (2) > when to use class methods and when to use functions ? > > In my opinion, both of class methods and functions have advantages and > disadvantages. I have to pass many arguments to a function, which is > annoying. When using class methods, the arguments can be stored as > attributes of the class, which is convenient for later use. But I have > to create an object in advance. I hope you know about all of it, but here it is, anyway: - In Python, *everything* is an object. - Whenever Python finds a class definition, it creates a *class object*. - A class objects acts as a *template* to create new objects called *instances* (of that class). - The template and the instance can both have *attributes* (to store data). - *Class attributes* can be accessed by both -- class as well as its instances. - *Instance attributes* can only be accesses by instances (because class doesn't have to know about these). - All the class attributes are shared among all the instances. If you change an attribute of a class, all the instances of that class (irrespective of when they were instantiated) will see the change. That gives us: - *Instance methods* (or simply, "methods") can access: class attributes, instance attributes, class methods, and instance methods. (And are accessible via an instance only.) - *Class methods* can ONLY access class attributes or other class methods. (And are accessible via the class or its instance.) - The first argument to instance methods is traditionally called "self" (which is an *instance object*) and that of class methods is called "cls" (which is a *class object*). Design choices: - The data which is to be shared by all the instances (and is mostly immutable) should be kept as class attribute (to minimize memory consumption). - The methods which should produce same result for all instances (and don't need to access instance attributes) should be declared as class methods. - Class attributes are also useful to *share state* among various instances (so that they can co-operate). Such "sharing functionality" is mostly implemented as class methods. It's just whatever I could recollect and thought might be relevant. I hope it helps. Arvind PS: Defining something as "property" suggests (to the class users) that it is inexpensive to access that value -- just a matter of style. -- http://mail.python.org/mailman/listinfo/python-list