[Baypiggies] Class methods as constructors?

Shannon -jj Behrens jjinux at gmail.com
Wed Sep 3 08:46:23 CEST 2008


Well argued.  Thanks for schoolin' me ;)

Now, if only you would have been around when I was stuck chaining
together factory methods to begin with so I wouldn't have had to make
that mistake!

-jj

On Tue, Sep 2, 2008 at 7:11 PM, Alex Martelli <aleax at google.com> wrote:
> Problem with a factory function is that it doesn't generate "the right
> subclass"; as a class gets subclassed, the subclasses' authors have to
> keep adding corresponding factory functions to make instances of
> _them_ instead of ones the original class.
>
> And whenever you see names such as the_factory, subclass1_the_factory,
> subclass2_the_factory, that's a very strong code smell: somebody's not
> using namespaces and object orientation right.  And "Namespaces are
> one honking great idea -- let's do more of those!", as the Zen of
> Python says as its rousing conclusion; basically, wanting to use
> factory functions instead of factory classmethods rejects this rousing
> applause for namespaces, and in a sense all of the Zen of Python.
>
> And yet, it's so *INCREDIBLY* easy...!  Consider:
>
>>>> class mydt(datetime.datetime): " some cool added functionality here "
> ...
>>>> mydt.fromordinal(999999)
> mydt(2738, 11, 27, 0, 0)
>
> Could it be any easier?  If the author of the datetime module had been
> so silly as to define a factor function datetime_fromordinal (instead
> of a class method of the datetime type) the poor author of the mydt
> subclass would have had to add their own laboriously named and
> boringly implemented mydt_fromordinal factory function -- presumably
> using the datetime_fromordinal factory to build a temporary datetime
> object, then copying the fields from those.  How much silly
> boilerplate and wasted work...!
>
> But luckily, the author of the datetime module didn't make that silly
> mistake: they defined a class method, and mydt automatically takes
> advantage of it, freely and easily.  Guess that module author
> understands and appreciates the Zen of Python, hm?
>
> Considering said author is Tim Peters, who also happened to *write*
> the Zen of Python, maybe that's not surprising;-).
>
> As for who's old-fashioned, well, my memory is a bit hazy after so
> long, but I believe I recall that Smalltalk '76 didn't yet have class
> methods, but Smalltalk '80 introduced them -- and the key use case has
> always been "alternate constructors" done RIGHT, as opposed to C++'s
> silly alternative of type-based overloading... who's to tell if a
> large number passed to a datetime constructor is meant as an ordinal
> or as a timestamp?!  Having fromordinal and fromtimestamp as
> separately named class methods puts paid to that!
>
> So, averaging the difference, I think I've been using class methods as
> alternate constructors starting about 30 years ago (though I had to
> forgo them for a sadly long time when using languages that just didn't
> HAVE factory methods). How much longer has YOUR
> so-called-old-fashioned preferred approach of "factory functions" been
> around?-)
>
>
> Alex
>
> On Tue, Sep 2, 2008 at 5:37 PM, Shannon -jj Behrens <jjinux at gmail.com> wrote:
>> On Tue, Sep 2, 2008 at 1:47 PM, Aahz <aahz at pythoncraft.com> wrote:
>>> On Tue, Sep 02, 2008, Charles Merriam wrote:
>>>>
>>>> I have a spot where I need a number of constructors for the same class
>>>> and don't want to have too complicated an __init__ function.   Using
>>>> class methods seems like the cleanest code.
>>>>
>>>> x = Spam()   # Simple case
>>>> x = Spam.Pickled_Loaf(['Pimentos','Menthos'])
>>>> x = Spam.Shake('chunky')
>>>>
>>>> with code in the Spam class like:
>>>>
>>>> @classmethod
>>>> def Picked_Loaf(additives, extra_gelatin = False):
>>>>      assert not ('Menthos' in additives and 'Diet Coke' in additives)
>>>>      i = Spam()  # make an instance
>>>>      i.additives = additives
>>>>      i.add_to_production_queue(Process.chopping)
>>>>      return i
>>>
>>> You probably don't want to use assert -- that gets optimized away with
>>> .pyo files.
>>>
>>> Overall, I personally would be more inclined to use a factory function
>>> or a slightly more complicated __init__ that dispatches, but there's
>>> nothing wrong with what you're doing.
>>
>> Call me old school, but I still use factory functions (i.e. outside
>> the class) like Aahz, but what you're doing is perfectly fine.
>>
>> -jj
>>
>> --
>> Don't you wish you had a really clever sig like mine?
>> http://jjinux.blogspot.com/
>> _______________________________________________
>> Baypiggies mailing list
>> Baypiggies at python.org
>> To change your subscription options or unsubscribe:
>> http://mail.python.org/mailman/listinfo/baypiggies
>>
>



-- 
Don't you wish you had a really clever sig like mine?
http://jjinux.blogspot.com/


More information about the Baypiggies mailing list