Dealing with non-callable classmethod objects

Ian Pilcher arequipeno at gmail.com
Sat Nov 12 11:34:24 EST 2022


On 11/11/22 16:47, Cameron Simpson wrote:
> On 11Nov2022 15:29, Ian Pilcher <arequipeno at gmail.com> wrote:
>> * Can I improve the 'if callable(factory):' test above?  This treats
>>  all non-callable objects as classmethods, which is obviously not
>>  correct.  Ideally, I would check specifically for a classmethod, but
>>  there doesn't seem to be any literal against which I could check the
>>  factory's type.
> 
> Yeah, it does feel a bit touchy feely.
> 
> You could see if the `inspect` module tells you more precise things 
> about the `factory`.
> 
> The other suggestion I have is to put the method name in `_attrs`; if 
> that's a `str` you could special case it as a well known type for the 
> factory and look it up with `getattr(cls,factory)`.

So I've done this.

     class _HasUnboundClassMethod(object):
         @classmethod
         def _classmethod(cls):
             pass  # pragma: no cover
         _methods = [ _classmethod ]

     _ClassMethodType = type(_HasUnboundClassMethod._methods[0])

Which allows me to do this:

     def __init__(self, d):
         for attr, factory in self._attrs.items():
             if callable(factory):
                 value = factory(d[attr])
             else:
                 assert type(factory) is self._ClassMethodType
                 value = factory.__func__(type(self), d[attr])
             setattr(self, attr, value)

It's a bit cleaner, although I'm not thrilled about having a throwaway
class, just to define a literal that ought to be provided by the
runtime.

-- 
========================================================================
Google                                      Where SkyNet meets Idiocracy
========================================================================



More information about the Python-list mailing list