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