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

 1 import math
2 class Circle:
3 def __init__(self,radius): #圆的半径radius
4 self.radius=radius
5
6 @property
7 def area(self):
8 return math.pi * self.radius**2 #计算面积
9
10 @property
11 def perimeter(self):
12 return 2*math.pi*self.radius #计算周长
13
14 c=Circle(10)
15 print(c.radius)
16 print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值
17 print(c.perimeter) #同上
18 '''
19 输出结果:
20 314.1592653589793
21 62.83185307179586
22 '''
注意:此时的特性arear和perimeter不能被赋值
'''
抛出异常:
AttributeError: can't set attribute
'''
2 为什么要用property

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

除此之外,看下

ps:面向对象的封装有三种方式:
【public】
这种其实就是不封装,是对外公开的
【protected】
这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开
【private】
这种封装对谁都不公开
python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现
 1 class Foo:
2 def __init__(self,val):
3 self.__NAME=val #将所有的数据属性都隐藏起来
4
5 @property
6 def name(self):
7 return self.__NAME #obj.name访问的是self.__NAME(这也是真实值的存放位置)
8
9 @name.setter
10 def name(self,value):
11 if not isinstance(value,str): #在设定值之前进行类型检查
12 raise TypeError('%s must be str' %value)
13 self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME
14
15 @name.deleter
16 def name(self):
17 raise TypeError('Can not delete')
18
19 f=Foo('egon')
20 print(f.name)
21 # f.name=10 #抛出异常'TypeError: 10 must be str'
22 del f.name #抛出异常'TypeError: Can not delete'
二、静态方法(staticmethod)                                                            

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

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

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

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

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

使用演示

print(type(Foo.spam)) #类型本质就是函数
Foo.spam(1,2,3) #调用函数应该有几个参数就传几个参数 f1=Foo()
f1.spam(3,3,3) #实例也可以使用,但通常静态方法都是给类用的,实例在使用时丧失了自动传值的机制 '''
<class 'function'>
2 3
3 3
'''
应用场景:编写类时需要采用很多不同的方式来创建实例,而我们只有一个__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)                                                                

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

class A:
x=1
@classmethod
def test(cls):
print(cls,cls.x) class B(A):
x=2
B.test()    #如果换成@staticmethod 就会报错缺少一个cls参数 '''
输出结果:
<class '__main__.B'> 2
'''
应用场景:
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 0x1013f9d68>
'''
因为e就是用Date类产生的,所以根本不会触发EuroDate.__str__,解决方法就是用classmethod
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) @classmethod #改成类方法
def now(cls):
t=time.localtime()
return cls(t.tm_year,t.tm_mon,t.tm_mday) #哪个类来调用,即用哪个类cls来实例化 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:2017 month:3 day:3
'''
强调,注意注意注意:静态方法和类方法虽然是给类准备的,但是如果实例去用,也是可以用的,只不过实例去调用的时候容易让人混淆,不知道你要干啥
x=e.now() #通过实例e去调用类方法也一样可以使用,静态方法也一样
print(x)
'''
输出结果:
year:2017 month:3 day:3
'''
 
四、附加知识点__str__的用法                                                               
#__str__定义在类内部,必须返回一个字符串类型,
#什么时候会出发它的执行呢?打印由这个类产生的对象时,会触发执行 class People:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '<name:%s,age:%s>' %(self.name,self.age) p1=People('egon',18)
print(p1)
str(p1) #----->p1.__str__()

特性(property)/静态方法(staticmethod)/类方法(classmethod)/__str__的用法的更多相关文章

  1. Python的3个方法:静态方法(staticmethod),类方法(classmethod)和实例方法

    Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

  2. 静态方法staticmethod类方法classmethod

    静态方法 只是名义上归类管理,实际上在静态方法里访问不了类或者实例中的任何属性. 类方法 只能访问类变量,不能访问实例变量 属性方法 把一个方法变成一个静态属性,调用的时候不能加() 如果这种属性方法 ...

  3. python-静态方法staticmethod、类方法classmethod、属性方法property

    Python的方法主要有3个,即静态方法(staticmethod),类方法(classmethod)和实例方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def  ...

  4. python中 staticmethod与classmethod

    原文地址https://blog.csdn.net/youngbit007/article/details/68957848 原文地址https://blog.csdn.net/weixin_3565 ...

  5. 【Python】@staticmethod和@classmethod的作用与区别

    前言 Python其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法,一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法.而使用@static ...

  6. python @staticmethod和@classmethod

    Python其实有3个方法,即 静态方法 (staticmethod), 类方法 (classmethod)和 实例方法. 如下: def foo(x): print "executing ...

  7. 面向对象【day08】:静态方法、类方法、属性方法(九)

    本节内容 概述 静态方法 类方法 属性方法 总结 一.概述 前面我们已经讲解了关于类的很多东西,今天讲讲类的另外的特性:静态方法(staticmethod).类方法(classmethod).属性方法 ...

  8. 【面试必问】python实例方法、类方法@classmethod、静态方法@staticmethod和属性方法@property区别

    [面试必问]python实例方法.类方法@classmethod.静态方法@staticmethod和属性方法@property区别 1.#类方法@classmethod,只能访问类变量,不能访问实例 ...

  9. python 3全栈开发-面向对象之绑定方法(classmethod与staticmethod的区别)、多态、封装的特性property

    一.面向对象绑定方法 一.类中定义的函数分成两大类 1.绑定方法(绑定给谁,谁来调用就自动将它本身当作第一个参数传入): 1. 绑定到类的方法:用classmethod装饰器装饰的方法. 为类量身定制 ...

随机推荐

  1. 通过Servlet获取初始化参数

    获取初始化参数在web.xml中配置Servlet时,可以配置一些初始化参数.而在Servlet中可以通过ServletConfig接口提供的方法来获取这些参数.(其实还可以通过ServletCont ...

  2. JSP小例子——实现用户登录小例子(不涉及DB操作)

    实现用户登录小例子用户名和密码都为"admin",登陆成功使用服务器内部转发到login_success.jsp页面,并且提示登陆成功的用户名.如果登陆失败则请求重定向到login ...

  3. Android之MessageQueue、Looper、Handler与消息循环

    在android的activity中有各种各样的事件,而这些事件最终是转换为消息来处理的.android中的消息系统涉及到: *  消息发送 *  消息队列 *  消息循环 *  消息分发 *  消息 ...

  4. Fiddler实现手机抓包——小白入门 - 做一个不动声色的大人

    手机用fiddler抓包 电脑最好是笔记本,这样能和手机保持统一局域网内:其他不多说,直接说步骤了. 一.对PC(笔记本)参数进行配置    1. 配置fiddler允许监听到https(fiddle ...

  5. D3D HOOK实现透视讲解

    实现目的: 目前大部分游戏通过Direct3D实现3D效果,通过挂钩相应函数,可以实现3D透视,屏幕挂字效果.而透视,屏蔽特定效果,设置透明在很多游戏(特别是FPS)中发挥着巨大的作用! 实现思路: ...

  6. LeetCode 笔记系列五 Generate Parentheses

    题目: Given n pairs of parentheses, write a function to generate all combinations of well-formed paren ...

  7. 关于如何将Eclipse中@author进行修改的解决方法

    问题:Eclipse和 MyEclipse上的文档注释"/**"里面的"@author Administrator"是自动生成的姓名,有时我们需要将自己的代码进 ...

  8. c#自定义控件做漂亮的列表

    效果图如下: 完整项目代码下载: 点击下载

  9. datasnap rest Windows客户端编写

    首先吐槽一下XE关于datasnap的资料真的是太少了... 服务端用DSHTTPService1控件可以实现http接口方式的调用,返回的都是json格式数据,适用于跨平台解析. 这里着重强调一下d ...

  10. 剑指Offer——不用加减乘除做加法

    题目描述: 写一个函数,求两个整数之和,要求在函数体内不得使用+.-.*./四则运算符号. 分析: "^"是不带进位的加法. "&"可以得到所有进位位组 ...