Part Two.

On Sun, Aug 11, 2019 at 10:58:37PM -0500, James Hartley wrote:


> from collections import namedtuple
> 
> class Foo():
>     Dimensions = namedtuple('Dimensions', ['height', 'width'])
>     _dimensions = Dimensions(3, 4)
> 
>     def dimensions():
>         print('id = {}'.format(id(Foo._dimensions)))
>         return Foo._dimensions
> 
>     @staticmethod
>     def dimensions1():
>         print('id = {}'.format(id(_dimensions)))
>         return _dimensions

> The class method Foo.dimensions() is capable of accessing class members,

Foo.dimensions is *not* a class method; it is a regular method that is 
written badly, and only works by accident.

It *seems* to be okay because when you try it like this:

    Foo.dimensions()  # call directly from the class object

you bypass some of the method magic, and get access to the regular 
function object, which in turn does a global lookup by name to find 
"Foo" and everything works from that point (although a bit slower than 
necessary).

But it doesn't work properly, because if you try to use it like this:

    Foo().dimensions()  # call from an instance

you'll get an error that the method takes no arguments but one is 
supplied.

To fix this, we can make it a proper classmethod like this:

class Foo():
    Dimensions = namedtuple('Dimensions', ['height', 'width'])
    _dimensions = Dimensions(3, 4)

    @classmethod
    def dimensions(cls):
        print('id = {}'.format(id(cls._dimensions)))
        return cls._dimensions


and now both Foo.dimensions() and Foo().dimensions() will work 
correctly, and as a bonus it ought to be a little faster.


Part 3 to follow.



-- 
Steven
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to