simple (I hope!) problem

samwyse samwyse at gmail.com
Thu Aug 5 09:44:30 EDT 2010


On Aug 5, 4:32 am, Jean-Michel Pichavant <jeanmic... at sequans.com>
wrote:
> samwyse wrote:
> > On Aug 3, 1:20 am, Steven D'Aprano <steve-REMOVE-
> > T... at cybersource.com.au> wrote:
>
> >> On Mon, 02 Aug 2010 17:19:46 -0700, samwyse wrote:
>
> >>> Fortunately, I don't need the functionality of the object, I just want
> >>> something that won't generate an error when I use it.  So, what is the
> >>> quickest way to to create such an object (replacing the 'pass' in my
> >>> first snippet).  My solution is this:
>
> >>>     class C:
> >>>         def filter(self, *args, **kwds):
> >>>             pass
> >>>     register = C()
>
> >>> but it seems like I should be able to do something "better", as measured
> >>> by lines of code, faking more than just a 'filter' method, or both.  Any
> >>> ideas?  Thanks!
>
> >> You want a variation on the Null Object design pattern.
>
> >> class NullWithMethods(object):
> >>     def __getattr__(self, name):
> >>         return self
> >>     def __call__(self, *args, **kwargs):
> >>         pass
>
> >> And in action:
>
> >>>>> c = NullWithMethods()
> >>>>> c.spam("hello", "world")
> >>>>> c.something_completely_unlikely.spam.ham("hello", "world", foo=42)
>
> >> --
> >> Steven
>
> > JM emailed me a good solution, but yours is great! Thanks!
>
> The version I gave you overrides __getattribute__. To be honest,
> overriding __getattr__ is a better solution.Just in case you don't know
> the difference, __getattr__ is called only if the attribute is not found
> while __getattribute__ is actually called to find the attribute.
>
> JM

I have to apologize for not replying as soon as I got your email.  It
did everything I needed, so I implemented it in my code and went to
town.  Then, when I did finally return to the c.l.py, there was an
solution that exceeded my needs by letting me chain together arbitrary
lists of attributes.  Now that I've slept on it, I've come up with a
solution that I like even more:

>>> class Placeholder(object):
    def __getattr__(self, name):
        return self
    def __getitem__(self, index):
	return self
    def __call__(self, *args, **kwargs):
        return self

>>> x = Placeholder()
>>> x('hello, world').y[42].z
<__main__.Placeholder object at 0x01E46490>

Yes, running it from the prompt looks ugly, but within a program the
return value is silently discarded.



More information about the Python-list mailing list