Re: More __init__ methods
On Fri, Nov 7, 2008 at 7:02 PM, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: >> What if I need the parse method to be called in other parts of the >> program? > > I don't understand!? Then you call it from those other parts. Yes, you're right. Don't know why, but I was thinking to use @classmethod just for the alternative constructors. -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Duncan Booth wrote: Mr.SpOOn <[EMAIL PROTECTED]> wrote: Now I must pass a and b to the main constructor and calculate them in the classmethods. class foo: def __init__(self, a, b): self.a = a self.b = b @classmethod def from_string(self, ..): ... ... What I mean is: I can't use anymore __init__ as the default constructor, but I always have to specify the way I'm creating my object. Am I right? I'm asking just to be sure I have understood. There is a really big advantage to being explicit in this situation: you no longer have to make sure that all your constructors use a unique set of types. Consider: class Location(object): def __init__(self, lat, long): ... @classmethod def from_city(name): ... @classmethod def from_postcode(name): ... 'from_string' is a bad name here for your factory method: you should try to make it clear what sort of string is expected. One built-in model for .__init__ + .from_data is dict. __init__ can take either one iterable or several keywords. In either case, it gets a set of key:value pairs. .from_keys take a set of keys and an optional value to override None that is matched with all keys. -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Fri, 07 Nov 2008 17:23:21 +0100, Mr.SpOOn wrote: > On Fri, Nov 7, 2008 at 4:16 PM, Duncan Booth > <[EMAIL PROTECTED]> wrote: >> There is a really big advantage to being explicit in this situation: >> you no longer have to make sure that all your constructors use a unique >> set of types. Consider: >> >> class Location(object): >>def __init__(self, lat, long): ... >> >>@classmethod >>def from_city(name): ... >> >>@classmethod >>def from_postcode(name): ... >> >> 'from_string' is a bad name here for your factory method: you should >> try to make it clear what sort of string is expected. > > Yes, that's what I was going to do. > But, for example, I have a parse method to create such object from a > string. So I need to call this method to actually create the object. Now > I must put the code of the parse method into the @classmethod > constructor. You can still spread it over other `classmethod()`\s or `staticmethod()`s or even plain functions at module level. > What if I need the parse method to be called in other parts of the > program? I don't understand!? Then you call it from those other parts. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Fri, Nov 7, 2008 at 4:16 PM, Duncan Booth <[EMAIL PROTECTED]> wrote: > There is a really big advantage to being explicit in this situation: you no > longer have to make sure that all your constructors use a unique set of > types. Consider: > > class Location(object): >def __init__(self, lat, long): ... > >@classmethod >def from_city(name): ... > >@classmethod >def from_postcode(name): ... > > 'from_string' is a bad name here for your factory method: you should try to > make it clear what sort of string is expected. Yes, that's what I was going to do. But, for example, I have a parse method to create such object from a string. So I need to call this method to actually create the object. Now I must put the code of the parse method into the @classmethod constructor. What if I need the parse method to be called in other parts of the program? -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Fri, 07 Nov 2008 15:16:29 +, Duncan Booth wrote: > 'from_string' is a bad name here for your factory method: you should try > to make it clear what sort of string is expected. When I use a `from_string()` factory I usually make sure it can parse the `str()` form of that type or that there is a `to_string()` as reverse operation. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Mr.SpOOn <[EMAIL PROTECTED]> wrote: > Now I must pass a and b to the main constructor and calculate them in > the classmethods. > > class foo: > def __init__(self, a, b): > self.a = a > self.b = b > > @classmethod > def from_string(self, ..): > ... > ... > > What I mean is: I can't use anymore __init__ as the default > constructor, but I always have to specify the way I'm creating my > object. Am I right? I'm asking just to be sure I have understood. There is a really big advantage to being explicit in this situation: you no longer have to make sure that all your constructors use a unique set of types. Consider: class Location(object): def __init__(self, lat, long): ... @classmethod def from_city(name): ... @classmethod def from_postcode(name): ... 'from_string' is a bad name here for your factory method: you should try to make it clear what sort of string is expected. -- Duncan Booth http://kupuguy.blogspot.com -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Thu, Nov 6, 2008 at 11:00 PM, Ben Finney <[EMAIL PROTECTED]> wrote: > Yes, the main reason is that it kills duck typing. The initialiser > should *use* the parameters passed, and allow exceptions to propagate > back to the caller if the parameters don't behave as expected. > > Another good reason to avoid the above style is that it's far too > complex. Different behaviours should be in different functions. Sorry for double posting, but in this way it seems I can't use instance method inside the classmethod. Probably it is the right behavior, but if I use this @classmethod style to simplify the __init__ method, now I should move code from instance method inside the classmethods. In this way I'm kinda mixing things. I mean, if to construct an object I have to use different methods, what can I do? Or am I missing something, as usual? -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Thu, Nov 6, 2008 at 11:00 PM, Ben Finney <[EMAIL PROTECTED]> wrote: > Yes, the main reason is that it kills duck typing. The initialiser > should *use* the parameters passed, and allow exceptions to propagate > back to the caller if the parameters don't behave as expected. > > Another good reason to avoid the above style is that it's far too > complex. Different behaviours should be in different functions. Ok, thanks. Is there a good book or source where I can read about such topics? Core Python Programming doesn't seem to talk about decorators. Maybe it's too old? -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Arnaud Delobelle <[EMAIL PROTECTED]> writes: > Ben Finney <[EMAIL PROTECTED]> writes: > [...] > > All you need to know to understand the above is that it will have > > essentially the same result as: > > > > class A(object): > > # ... > > > > def _from_string(cls, s): > > # ... > > return cls(a, b, c) > > from_string = classmethod(_from_string) > > del _from_string > > > > without the intermediate binding of the ‘_from_string’ name. > > So you mean it is the same as: > > class A(object): > # ... > > def from_string(cls, s): > # ... > from_string = classmethod(from_string) Sure, but I figured I would make the steps more explicit. -- \ “Writing a book is like washing an elephant: there no good | `\place to begin or end, and it's hard to keep track of what | _o__) you've already covered.” —anonymous | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Larry Bates <[EMAIL PROTECTED]> writes: > Is there some reason not to use something like the following? > > class foo: > def __init__(self, val): > self.a = 0 > self.b = 0 > > if isinstance(val, basestring): > # > # do something to calculate "a and b" > # > > elif isintance(val, int): > # > # do something else to calculate "a and b" > # > > elif isinstance(val, someinstance) > # > # do something else to calculate "a and b" > # > > else: > # > # Don't know what to do with unknown type > # > raise ValueError() Yes, the main reason is that it kills duck typing. The initialiser should *use* the parameters passed, and allow exceptions to propagate back to the caller if the parameters don't behave as expected. Another good reason to avoid the above style is that it's far too complex. Different behaviours should be in different functions. -- \ “Friendship is born at that moment when one person says to | `\another, ‘What! You too? I thought I was the only one!’” —C.S. | _o__)Lewis | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Mr.SpOOn <[EMAIL PROTECTED]> writes: > class foo: > def __init__(self, a, b): > self.a = a > self.b = b > > @classmethod > def from_string(self, ..): > ... > ... > > What I mean is: I can't use anymore __init__ as the default > constructor, but I always have to specify the way I'm creating my > object. Am I right? I'm asking just to be sure I have understood. Yes, that's what the above design requires. You code ‘foo.__init__’ for the common use case, and create ‘foo.from_bar’ classmethod factory functions for other cases. The caller then needs to specify which case is being requested. -- \ “I was in the first submarine. Instead of a periscope, they had | `\ a kaleidoscope. ‘We're surrounded.’” —Steven Wright | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Ben Finney <[EMAIL PROTECTED]> writes: [...] > All you need to know to understand the above is that it will have > essentially the same result as: > > class A(object): > # ... > > def _from_string(cls, s): > # ... > return cls(a, b, c) > from_string = classmethod(_from_string) > del _from_string > > without the intermediate binding of the ‘_from_string’ name. So you mean it is the same as: class A(object): # ... def from_string(cls, s): # ... from_string = classmethod(from_string) :) -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Mr.SpOOn <[EMAIL PROTECTED]> writes: > On Thu, Nov 6, 2008 at 4:59 PM, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> > wrote: > > class A(object): > >def __init__(self, a, b, c): > >self.a = a > ># ... > > > >@classmethod > >def from_string(cls, s): > ># ... > >return cls(a, b, c) > > Thanks. > I think it's time to study decorators. Studying decorators is a good idea, but in this instance it's not necessary. The above is merely using decorator syntax to apply the ‘classmethod’ type to a function. All you need to know to understand the above is that it will have essentially the same result as: class A(object): # ... def _from_string(cls, s): # ... return cls(a, b, c) from_string = classmethod(_from_string) del _from_string without the intermediate binding of the ‘_from_string’ name. -- \ “The best way to get information on Usenet is not to ask a | `\ question, but to post the wrong information.” —Aahz | _o__) | Ben Finney -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Mr.SpOOn wrote: On Thu, Nov 6, 2008 at 7:44 PM, Tim Golden <[EMAIL PROTECTED]> wrote: While that's no bad thing, you don't really need to do that simply to understand these examples: they're just saying "do whatever you need to to make these method class methods, not instance methods". Yes. I think this changes the design of my class. I mean, till now I had something like: class foo: def __init__(self, string=None, integer=None, someinstance=None): self.a = 0 self.b = 0 if string: # do something to calculate "a and b" elif integer: # do something else to calculate "a and b" ... ... So I used different methods to calculate the same variables. Now I must pass a and b to the main constructor and calculate them in the classmethods. class foo: def __init__(self, a, b): self.a = a self.b = b @classmethod def from_string(self, ..): ... ... What I mean is: I can't use anymore __init__ as the default constructor, but I always have to specify the way I'm creating my object. Am I right? I'm asking just to be sure I have understood. Is there some reason not to use something like the following? class foo: def __init__(self, val): self.a = 0 self.b = 0 if isinstance(val, basestring): # # do something to calculate "a and b" # elif isintance(val, int): # # do something else to calculate "a and b" # elif isinstance(val, someinstance) # # do something else to calculate "a and b" # else: # # Don't know what to do with unknown type # raise ValueError() -Larry -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Thu, Nov 6, 2008 at 7:44 PM, Tim Golden <[EMAIL PROTECTED]> wrote: > While that's no bad thing, you don't really need to do > that simply to understand these examples: they're just > saying "do whatever you need to to make these method > class methods, not instance methods". Yes. I think this changes the design of my class. I mean, till now I had something like: class foo: def __init__(self, string=None, integer=None, someinstance=None): self.a = 0 self.b = 0 if string: # do something to calculate "a and b" elif integer: # do something else to calculate "a and b" ... ... So I used different methods to calculate the same variables. Now I must pass a and b to the main constructor and calculate them in the classmethods. class foo: def __init__(self, a, b): self.a = a self.b = b @classmethod def from_string(self, ..): ... ... What I mean is: I can't use anymore __init__ as the default constructor, but I always have to specify the way I'm creating my object. Am I right? I'm asking just to be sure I have understood. -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Mr.SpOOn wrote: On Thu, Nov 6, 2008 at 4:59 PM, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: class A(object): def __init__(self, a, b, c): self.a = a # ... @classmethod def from_string(cls, s): # ... return cls(a, b, c) Thanks. I think it's time to study decorators. While that's no bad thing, you don't really need to do that simply to understand these examples: they're just saying "do whatever you need to to make these method class methods, not instance methods". TJG -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Thu, Nov 6, 2008 at 4:59 PM, Marc 'BlackJack' Rintsch <[EMAIL PROTECTED]> wrote: > class A(object): >def __init__(self, a, b, c): >self.a = a ># ... > >@classmethod >def from_string(cls, s): ># ... >return cls(a, b, c) Thanks. I think it's time to study decorators. -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
On Thu, 06 Nov 2008 16:49:08 +0100, Mr.SpOOn wrote: > I know there can be only one __init__ method (at least, I think). > > Often I need an object to be created in different ways, for example > passing a string as argument, or an integer, or another object. To > achieve this I put the default value of the arguments to None and then I > some if...elif inside the __init__. > > Is this a good practice? It actually works, but sometimes I think that > in this way the __init__ method can become too complicated, for example > when an object can be created using more than one argument and in > different combinations. I'm usually using `classmethod()`\s as alternative "constructors" then. For example: class A(object): def __init__(self, a, b, c): self.a = a # ... @classmethod def from_string(cls, s): # ... return cls(a, b, c) Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list
Re: More __init__ methods
Mr.SpOOn wrote: Hi, I know there can be only one __init__ method (at least, I think). Often I need an object to be created in different ways, for example passing a string as argument, or an integer, or another object. To achieve this I put the default value of the arguments to None and then I some if...elif inside the __init__. Is this a good practice? It actually works, but sometimes I think that in this way the __init__ method can become too complicated, for example when an object can be created using more than one argument and in different combinations. My own approach -- and I don't think I'm unique in this -- is to use class methods called things like "from_string" or "from_date", possibly with a convenience function which tries to guess from a passed-in parameter which of them is to be used. TJG -- http://mail.python.org/mailman/listinfo/python-list
More __init__ methods
Hi, I know there can be only one __init__ method (at least, I think). Often I need an object to be created in different ways, for example passing a string as argument, or an integer, or another object. To achieve this I put the default value of the arguments to None and then I some if...elif inside the __init__. Is this a good practice? It actually works, but sometimes I think that in this way the __init__ method can become too complicated, for example when an object can be created using more than one argument and in different combinations. Hope my doubt is clear. -- http://mail.python.org/mailman/listinfo/python-list