zz1999

导航

 

静态方法

静态方法是一类特殊的方法,有时你可能需要写一个属于这个类的方法,但是这些代码完全不会使用到实例对象本身,例如:

class Pizza(object):
    @staticmethod
    def mix_ingredients(x, y):
        return x + y

    def cook(self):
       return self.mix_ingredients(self.cheese, self.vegetables)

这个例子中,如果把mix_ingredients作为非静态方法同样可以运行,但是它要提供self参数,而这个参数在方法中根本不会被使用到

这里的@staticmethod装饰器可以给我们带来一些好处:

  1 Python不再需要为Pizza对象实例初始化一个绑定方法,绑定方法同样是对象,但是创建他们需要成本,而静态方法就可以避免这些。

  2 可读性更好的代码,看到@staticmethod我们就知道这个方法并不需要依赖对象本身的状态。

  3  可以在子类中被覆盖,如果是把mix_ingredients作为模块的顶层函数,那么继承自Pizza的子类就没法改变pizza的mix_ingredients了如果不覆盖cook的话。

 

类方法

什么是类方法呢?类方法不是绑定到对象上,而是绑定在类上的方法。

class Pizza(object):

  radius = 42

  @classmethod

  def get_radius(cls):

      return cls.radius

无论你用哪种方式访问这个方法,它总是绑定到了这个类身上,它的第一个参数是这个类本身(记住:类也是对象)。 

 

什么时候使用这种方法呢?类方法通常在以下两种场景是非常有用的:

1 工厂方法:它用于创建类的实例,例如一些预处理。如果使用@staticmethod代替,那我们不得不硬编码Pizza类名在函数中,这使得任何继承Pizza的类都不能使用我们这个工厂方法给它自己用。

class Pizza(object):
       def __init__(self, ingredients):
           self.ingredients = ingredients

      @classmethod
      def from_fridge(cls, fridge):
         return cls(fridge.get_cheese() + fridge.get_vegetables())

 

2 调用静态类:如果你把一个静态方法拆分成多个静态方法,除非你使用类方法,否则你还是得硬编码类名。使用这种方式声明方法,Pizza类名明永远都不会在被直接引用,继承和方法覆盖都可以完美的工作。

class Pizza(object):
     def __init__(self, radius, height):
          self.radius = radius
          self.height = height

    @staticmethod
    def compute_area(radius):
        return math.pi * (radius ** 2)

   @classmethod
   def compute_volume(cls, height, radius):
       return height * cls.compute_area(radius)

   def get_volume(self):
       return self.compute_volume(self.height, self.radius)

 

继承类中的区别

从下面代码可以看出,如果子类继承父类的方法,子类覆盖了父类的静态方法,
子类的实例继承了父类的static_method静态方法,调用该方法,还是调用的父类的方法和类属性。
子类的实例继承了父类的class_method类方法,调用该方法,调用的是子类的方法和子类的类属性。

 

class Foo(object):
    X = 1
    Y = 2

    @staticmethod
    def averag(*mixes):
        return sum(mixes) / len(mixes)

    @staticmethod
    def static_method():
        return Foo.averag(Foo.X, Foo.Y)

    @classmethod
    def class_method(cls):
        return cls.averag(cls.X, cls.Y)


class Son(Foo):
    X = 3
    Y = 5

    @staticmethod
    def averag(*mixes):
        return sum(mixes) / 3

p = Son()
print(p.static_method())
print(p.class_method())
# 1.5
# 2.6666666666666665

 

posted on 2019-05-20 11:39  zz1999  阅读(174)  评论(0)    收藏  举报