python3(property、staticmethod、classmethod)

特性(property)
静态方法(staticmethod)
类方法(classmethod)

一、特性property

property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

1、什么事特性property

import math
   
class Circle:
    def __init__(self,radius):
        self.radius =radius
 
    @property
    def area(self):
        return math.pi*self.radius**2 #计算圆的面积
 
    @property
    def perimeter(self):
        return 2*math.pi*self.radius  #计算圆的周长
 
c = Circle(5)
print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
print(c.perimeter)

输出结果
78.53981633974483
31.41592653589793

注意:此时的特性arear和perimeter不能被赋值,一旦赋值就会报错

2、 为什么要用property

将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

除此之外,看下

面向对象的封装有三种方式:
【public】
这种其实就是不封装,是对外公开的
【protected】
这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
【private】
这种封装对谁都不公开

python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现


__author__ = 'rxz'
# -*- encoding:utf-8 -*-
import math
 
 
class Foo:
    def __init__(self,name):
        self.__Name =name #将所有的数据属性都隐藏起来
 
    @property
    def get_name(self):
        return self.__Name #obj.name访问的是self.__NAME(这也是真实值的存放位置)
 
    @get_name.setter
    def set_name(self,value):
        if not isinstance(value,str): #在设定值之前进行类型检查
            raise TypeError('%s must be str' % value)
        self.__Name = value #通过类型检查后,将值value存放到真实的位置self.__NAME
 
    @get_name.deleter
    def del_name(self):
        raise TypeError('Can not delete')
 
f =Foo("lida")
print(f.get_name)
f.set_name = "wer"
print(f.get_name)
del f.get_name

输出结果

lida
Traceback (most recent call last):
wer
File "C:/Users/Administrator/PycharmProjects/ManagerSystem/test/a.py", line 28, in <module>
del f.get_name
AttributeError: can't delete attribute

二、静态方法(staticmethod)

通常情况下,在类中定义的所有函数(注意了,这里说的就是所有,跟self啥的没关系,self也只是一个再普通不过的参数而已)都是对象的绑定方法,对象在调用绑定方法时会自动将自己作为参数传递给方法的第一个参数。除此之外还有两种常见的方法:静态方法和类方法,二者是为类量身定制的,但是实例非要使用,也不会报错。

是一种普通函数,位于类定义的命名空间中,不会对任何实例类型进行操作,python为我们内置了函数staticmethod来把类中的函数定义成静态方法

class Foo:
    def test(x,y,z): #类中的一个函数,千万不要懵逼,self和x啥的没有不同都是参数名
        print(x,y,z)
    t=staticmethod(test) #把test函数做成静态方法    

基于之前所学装饰器的知识,@staticmethod 等同于spam=staticmethod(spam),于是

class Foo:
    @staticmethod #装饰器
    def test(x,y,z):
        print(x,y,z)

使用演示

class Foo:
    @staticmethod
    def test(x,y,z):
        print(x,y,z)
 
 
print(type(Foo.test))#类型本质就是函数
Foo.test(1,2,3) #调用函数应该有几个参数就传几个参数
 
f1=Foo()
f1.test(3,67,99) #实例也可以使用,但通常静态方法都是给类用的,实例在使用时丧失了自动传值的机制

输出结果:

<class 'function'>
1 2 3
3 67 99

应用场景:编写类时需要采用很多不同的方式来创建实例,而我们只有一个init函数,此时静态方法就派上用场了

class Date:
    def __init__(self,year,month,day):
        self.year=year
        self.month=month
        self.day=day
    @staticmethod
    def now(): #用Date.now()的形式去产生实例,该实例用的是当前时间
        t=time.localtime() #获取结构化的时间格式
        return Date(t.tm_year,t.tm_mon,t.tm_mday) #新建实例并且返回
    @staticmethod
    def tomorrow():#用Date.tomorrow()的形式去产生实例,该实例用的是明天的时间
        t=time.localtime(time.time()+86400)
        return Date(t.tm_year,t.tm_mon,t.tm_mday)
 
a=Date('1987',11,27) #自己定义时间
b=Date.now() #采用当前时间
c=Date.tomorrow() #采用明天的时间
 
print(a.year,a.month,a.day)
print(b.year,b.month,b.day)
print(c.year,c.month,c.day)

三、类方法(classmethod)

类方法是给类用的,类在使用时会将类本身当做参数传给类方法的第一个参数,python为我们内置了函数classmethod来把类中的函数定义成类方法

class A:
    x=1
 
    @classmethod
    def test(cls):
        print(cls,cls.x)
 
class B(A):
    x=2
 
B.test()

输出结果:

<class 'main.B'> 2

应用场景:

# -*- encoding:utf-8 -*-
import time
 
 
class Date:
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day
 
    @staticmethod
    def now():
        t = time.localtime()
        return Date(t.tm_year,t.tm_mon,t.tm_mday)
 
 
class EuroDate(Date):
    def __str__(self):
         return "year:%s month:%s day:%s" %(self.year,self.month,self.day)
 
 
e = EuroDate.now()
print(e)  #我们的意图是想触发EuroDate.__str__,但是结果为

输出结果:

<main.Date object at 0x00000000021CCCC0>

因为e就是用Date类产生的,所以根本不会触发EuroDate.str,解决方法就是用classmethod

import time
 
 
class Date:
    def __init__(self,year,month,day):
        self.year = year
        self.month = month
        self.day = day
 
    @classmethod #改成类方法
    def now(cls):
        t = time.localtime()
        return cls(t.tm_year,t.tm_mon,t.tm_mday)
 
 
class EuroDate(Date):
    def __str__(self):
         return "year:%s month:%s day:%s" %(self.year,self.month,self.day)
 
 
e = EuroDate.now()
print(e)  #我们的意图是想触发EuroDate.__str__,此时e就是由EuroDate产生的,所以会如我们所愿

输出结果:

year:2018 month:9 day:29

强调,注意注意注意:静态方法和类方法虽然是给类准备的,但是如果实例去用,也是可以用的,只不过实例去调用的时候容易让人混淆,不知道你要干啥

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容