Aric Zeng

极致的高深即是简单——列奥纳多.达.芬奇

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

请利用@property给一个Screen对象加上widthheight属性,以及一个只读属性resolution

写了一段代码

class Screen(object):
    #利用property装饰器负责把width方法变成属性调用
    @property
    def width(self):
        return self._width
    #定义setter方法变成可读属性,如果不定义getter方法,就是只读属性
    @width.setter
    def width(self, value):
        self._width = value
    #同width    
    @property 
    def height(self):
        return self._height
    #同width
    @height.setter
    def height(self, value):
        self._height = value
    #将resolution变成一个只读属性,并打印出来
    @property 
    def resolution(self):
        print("%s * %s == %d" %(self._width, self._height, self._width*self._height))

测试一下,#test

s = Screen()
s.width = 1024
s.height = 768
s.resolution

输出结果:

1024 * 768 == 786432

上面是一个简单没有进行属性控制的语句,能够实现功能,但在网上看到另外一种情况,就是要对相关方法属性进行raise抛出异常操作

增加了一个@staticmethod 静态方法,觉得挺好,后来又看到了除了staticmethod静态方法还有classmethod类方法,在这里也普及一下

改进后的代码

class Screen(object):
    def __init__(self):
        self._height = 0
        self._width = 0
    
    @staticmethod
    def _check_param(value):
        if not isinstance(value, int):
            raise TypeError('必须是一个整数类型!')
        if value <= 0:
            raise ValueError('必须是大于0的数!')
        
    #利用property装饰器负责把width方法变成属性调用
    @property
    def width(self):
        return self._width
    #定义setter方法变成可读属性,如果不定义getter方法,就是只读属性
    @width.setter
    def width(self, value):
        self._check_param(value)
        self._width = value
    #同width    
    @property 
    def height(self):
        return self._height
    #同width
    @height.setter
    def height(self, value):
        self._check_param(value)
        self._height = value
    #将resolution变成一个只读属性,并打印出来
    @property 
    def resolution(self):
        print("%s * %s == %d" %(self._width, self._height, self._width*self._height))

测试一下:

s = Screen()
s.width = -1024

输出:ValueError: 必须是大于0的数!

接下来看一下之前的问题staticmethod和classmethod方法,参考:http://www.cnblogs.com/Tony-zhangl/p/4687889.html

static method定义:静态方法是一类特殊的方法。有时,你想写一些属于类的代码,但又不会去使用和这个类任何相关的东西。(很抽象),基本上和一个全局函数差不多,可以通过类或者类的实例对象进行调用,不会隐式地传入任何参数。

class method定义:什么是类方法,类方法不是绑定到类的实例上去的,而是绑定到类上去的.(也很抽象),是和一个class类相关的方法,可以通过类或类实例进行调用,并将该class对象(不是class的实例对象)隐式地当作第一个参数传入。

 

区别:类方法需要额外的类变量cls,调用类方法传入的类变量cls是子类,而不是父类。类方法和静态方法都可以通过类对象和类的实例对象访问。

class MyClass(object):
    var = "test for myclass"
    
    @classmethod
    def clsmethod(cls):
        print(cls.var)
    @staticmethod
    def sticmethod():
        print(MyClass.var)

s = MyClass()
s.clsmethod()
s.sticmethod()

输出结果

s.clsmethod()
test for myclass

s.sticmethod()  
test for myclass

另外一个显然的对比例子如下

class ParentClass(object):
    
    var = "test for parent"

    @classmethod
    def clsmethod(cls):
        print cls.var

class SubClass(ParentClass):
    
    var = "test for sub"

此时ParentClass.clsmethod输出为 “test for parent”,而Subclass.clsmethod输出为“test for sub”,通过此比较很好的诠释了@classmethod类方法隐式传入的第一个参数是当前类,而不是父类。同时类方法操作的是class 类对象提供的内部信息。而staticmethod可以作为一般的工具函数来使用。

 

posted on 2017-06-06 10:41  一阵风,静!  阅读(248)  评论(0编辑  收藏  举报