4.4 Static methods Static methods return the underlying function without changes. Calling either$_{c.f}$ or$_{C.f}$is the equivalent of a direct lookup into$_{object.__getattribute__(c, "f")}$ or$_{object.__getattribute__(C, "f")}$ . As a result, the function becomes identically accessible from either an object or a class. Good candidates for static methods are methods that do not reference the$_{self}$variable. For instance, a statistics package may include a container class for experimental data. The class provides normal methods for computing the average, mean, median, and other descriptive statistics that depend on the data. However, there may be useful functions which are conceptually related but do not depend on the data. For instance, erf(x) is handy conversion routine that comes up in statistical work but does not directly depend on a particular dataset. It can be called either from an object or the class: s.erf(1.5) --> .9332 or . Since static methods return the underlying function with no changes, the example calls are unexciting: Using the non-data descriptor protocol, a pure Python version of$_{staticmethod()}$ would look like this: Unlike static methods, class methods prepend the class reference to the argument list before calling the function. This format is the same for whether the caller is an object or a class: This behavior is useful whenever the method only needs to have a class reference and does not rely on data stored in a specific instance. One use for class methods is to create alternate class constructors. For example, the classmethod dict.fromkeys() creates a new dictionary from a list of keys. The pure Python equivalent is: 16 classDict (dict): @classmethod def fromkeys(cls, iterable, value = None ): "Emulate dict_fromkeys() in Objects/dictobject.c " (continues on next page) >>> F .f(3) ('F', 3) >>> F().f(3) ('F', 3) classF : @classmethod def f(cls, x): return cls.__name__ , x classStaticMethod : "Emulate PyStaticMethod_Type() in Objects/funcobject.c " def __init__ (self, f): self.f =f def __get__ (self, obj, objtype = None ): return self.f >>> E.f(3) 30 >>> E() .f(3) 30 classE : @staticmethod def f(x): return x *10 4.5 Class methods