2.4.4 类方法
本节目标:
掌握
@classmethod,@staticmethod,@property几个装饰器。完成本周的大~作~业~
Learning By Reading 难度:★ 重要性:★★★★★
class MyTurtle(turtle.Turtle):
_all_turtles = {} # 用一个dict将小海龟名字和小海龟对象本身对应起来
def __init__(self, name, *args, **kwds):
super(MyTurtle).__init__(*args, **kwds)
self.name = name
MyTurtle._all_turtles[name] = self
@property
def n_turtles(self):
return len(MyTurtle._all_turtles)
@classmethod
def get_by_name(cls, name):
return cls._all_turtles[name]
ada = MyTurtle('ada')
another_ada = MyTurtle.get_by_name('ada')
if ada == another_ada:
print("相等!")
print(ada.n_turtles) # 结果:1注意property只能用在对象上,如果MyTurtle.n_turtles会返回一个property类型对象。
Learning By Thinking 难度:★★★★ 重要性:★★★★
classmethod、staticmethod、property都是装饰器,想想它们可以怎样实现。
Learning By Doing 难度:★★★★ 重要性:★★
试着实现
MyClassmethod、MyStaticmethod、MyProperty,让它们基本具有和classmethod、staticmethod、property同样的功能。
我来选一个最难的staticmethod解释一下~
先观察一下
class MyClass(object):
def method_1(self):
pass
@staticmethod
def sm_1():
pass
print(type(MyClass.method_1)) # function
print(type(MyClass.sm_1)) # function
print(type(MyClass().method_1)) # method
print(type(MyClass().sm_1)) # function也就是说,普通的方法,当通过类名来调用时,它是一个function,而通过一个对象来调用时,是一个method。 但一个staticmethod怎么都是function。
所以我们的目标是实现一个让function不管被类还是被对象调用时都得到function的装饰器。
class MyStaticmethod(object):
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return self.func
class MyClass(object):
@MyStaticmethod
def some_staticmethod(some_value):
return some_value__get__是一个魔术方法,定义了当前对象如何被作为别的对象的属性获取, a.b等价于a.b.__get__(a, a.__class__)。
Learning By Doing 难度:★★★★ 重要性:★★★
之前我们定义了n_turtles这个property,property只能用对象调用,但“MyTurtle有多少个海龟”, 即MyTurtle.n_turtles,比“ada有多少海龟”,即ada.n_turtles听起来更合理一些。 你能设计一个继承了property的ClassProperty完成这个需求吗?
Learning By Doing 难度:★★★★★ 重要性:★★★★★
阶段性测试:
画一个随机生成的迷宫
把小海龟放在里面,让它自己走出来。
如何迷宫生成参考这里。
Last updated