首页 > 编程语言 >python 基础--类

python 基础--类

时间:2022-12-05 12:05:18浏览次数:31  
标签:__ return name python self 基础 -- score def


文章目录

  • ​​面向对象编程--python 类​​
  • ​​类特殊的系统变量​​
  • ​​`__slots__`​​
  • ​​`@property`​​
  • ​​`__str__`​​
  • ​​`__iter__`​​
  • ​​`__getitem__`​​
  • ​​`__getattr__`​​
  • ​​`__call__`​​

面向对象编程–python 类

本文学习自廖雪峰老师的教程,如果想要系统学习请点廖雪峰的python教程

类特殊的系统变量

​__slots__​

_slots_ = (‘name’, ‘age’) # 用tuple定义允许绑定的属性名称,注意此限制对子类不影响

class Student():
__slots__ = ('score','name')

​@property​

为了方便的调用属性,python提供了@property装饰器

class Student():
@property # property修饰的函数可以使用属性,并且property会创建@score.setter进行属性赋值,如果不适用@score.setter属性则表示只读
def score(self):
return self._score # 注意内部将变量添加_或者__表示私有变量,不允许访问,但是__的其实可以通过_Student__score和_score访问
@score.setter
def score(self,value):
if not isinstance(value,int):
raise ValueError('score must be an integer!')
if value<0 or value>100 :
raise ValueError('value must between 0~100')
self._score = value

注意:如果不把score变量声明为_score, 那么score(self, value)为了得出最后的self.score = value,会对self.score这个函数进行循环调用。如果声明了, self._score = value,那么很明显self._score必定是变量,就会一次性得出结果
举一个例子:利用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution

class Screen(object):
@property
def width(self):
return self._width
@width.setter
def width(self,width):
self._width = width
@property
def height(self):
return self._height
@height.setter
def height(self, height):
self._height = height
@property
def resolution(self):
return self._width*self._height

​__str__​

__str__用于自定义打印一个实例,代码如下

class Student():
def __init__(self,name):
self.name = name
def __str__(self):
return ('student name:%s') % self.name

​>>>print(Student('Micyle'))​​​ 打印出来后
​student name:Micyle​​ 但如果我们直接敲变量,还是之前的变量地址

>>>s = Student('Micyle')
>>>s
<__main__.Student at 0x10b0996d8>

这是因为直接敲变量调用的是__repr__而不是__str__,str()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,repr()是为调试服务的。
我们可以再定义一个__repr__,也可以直接把__str__赋给__repr__

class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name=%s)' % self.name
__repr__ = __str__

​__iter__​

如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。

class Fib(object):
def __init__(self):
self.a,self.b = 0,1
def __iter__(self):
return self
def __next__(self):
self.a,self.b = self.b,self.a+self.b
if self.a > 1000:
raise StopIteration()
return self.a
for i in Fib():
print(i)

​__getitem__​

Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,取第5个元素:
​​​>>>Fib()[5]​​ 会报错,这里我们可以使用__getitem__

class Fib(object):
def __getitem__(self,n):
a,b = 0,1
for i in range(n):
a,b = b,a+b
return a # 这里其实返回的一个a的列表

但是如果我们使用切片方法,会报错
​​​Fib()[5:10]​​ 这是因为__getitem__()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断:

class Fib(object):
def __getitem__(self,n): # getitem将返回的值组成一个列表的形式,而返回的L也是一个列表,因而是列表中的元素还是列表
if isinstance(n,int):
a,b = 1,1
for i in range(n):
a,b = b,a+b
return a
elif isinstance(n,slice):
a,b = 1,1
start = n.start
stop = n.stop
if n.start is None:
start = 0
l = []
for i in range(n.stop):
if i>=start:
l.append(a)
a,b = b,a+b
return l

也没有对负数作处理,所以,要正确实现一个__getitem__()还是有很多工作要做的。此外,如果把对象看成dict,getitem()的参数也可能是一个可以作key的object,例如str。
与之对应的是__setitem__()方法,把对象视作list或dict来对集合赋值。最后,还有一个__delitem__()方法,用于删除某个元素。
总之,通过上面的方法,我们自己定义的类表现得和Python自带的list、tuple、dict没什么区别,这完全归功于动态语言的“鸭子类型”,不需要强制继承某个接口。

​__getattr__​

当我们调用类的方法或属性时,如果不存在,就会报错。比如定义Student类,如果没有定义score属性,调用就会报错

class Student():
def __init__(self):
self.name = 'Micyle'
s = Student()
s.score

要避免这个错误,除了可以加上一个score属性外,Python还有另一个机制,那就是写一个__getattr__()方法,动态返回一个属性。

class Student():
def __init__(self):
self.name = 'Micyle'
def __getattr__(self,attr):
if attr=='score':
return 99

当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, ‘score’)来尝试获得属性,这样,我们就有机会返回score的值:

class Student():
def __init__(self):
self.name = 'Micyle'
def __getattr__(self,attr):
if attr=='score':
return lambda :1+2
a = Student()
a.score()

只需调用​​a.score()​​​可以返回函数运算值
注意:只有在没有找到属性的情况下,才调用__getattr__,已有的属性,比如name,不会在__getattr__中查找。
此外,注意到任意调用如s.abc都会返回None,这是因为我们定义的__getattr__默认返回就是None。要让class只响应特定的几个属性,我们就要按照约定,抛出AttributeError的错误:

class Student():
def __init__(self):
self.name = 'Micyle'
def __getattr__(self,attr):
if attr=='score':
return lambda :1+2
raise AttributeError('student object has no %s'%attr)

举一个很好的例子应用getattr方法,输出给每个URL对应的API

class Chain(object):
def __init__(self, path=''):
self._path = path
def __getattr__(self, path):
return Chain('%s/%s' % (self._path, path))
def __str__(self):
return self._path
__repr__ = __str__

通过调用​​Chain('xxx').status.user.timeline.list​​​可以得到如下结果
​​​xxx/status/user/timeline/list​​​ 部分api的生成包含了用户名,如果可以采用以下方式调用就比较方便
​Chain().users('michael').repos​​ 可以用以下代码实现

class Chain(object):
def __init__(self, path=''):
self._path = path
def __getattr__(self, path):
return Chain('%s/%s' % (self._path, path))
def __str__(self):
return self._path
def users(self,str):
return Chain('%s/%s'%(self._path,'/users/' + str))
__repr__ = __str__

​__call__​

实例有自己的属性和方法,通过instance.method()来调用,同时也可以直接通过实例调用,只需要定义一个__call__()方法

class Student(object):
def __init__(self,name):
self.name = name
def __call__(self):
print(self.name)

通过__call__()方法就只可以直接调用实例方法
​​​a = Student('song')​​​​a()​​ 另外,函数与对象没有根本的区别,我们可以通过callable来判断对象能否被调用
​callable(a)​​ 结果为​​True​


标签:__,return,name,python,self,基础,--,score,def
From: https://blog.51cto.com/u_15899958/5911835

相关文章

  • 小米AI推理框架MACE介绍
    MACE是小米公司自研的移动端深度学习框架MobileAIComputeEngine,2017年12月15日于公司内部正式发布。2018年6月28日,在“2018(第十三届)开源中国开源世界高峰论坛”上,小米......
  • 利用傅立叶变换进行图像处理的代码演示
    前面有篇文件介绍过使用DCT(离散余弦)变换进行图像处理的例子:方法和思路: 关于傅立叶变换的实践,可以参考这篇文章:代码演示:高频滤波操作:#-*-coding:utf-8-*-importnumpyimpo......
  • UVC设备端驱动的实现原理分析
    UVC工作原理:关于UVC的实现方式,UVC驱动分为设备端和主机端,根据linux内核的实现,貌似设备端的实现源码头部的版本信息描述为“USBVideoClassGadgetdriver”,而主机端的实......
  • Sunxi平台上通过DirectFB绘制文本遇到的一个问题
    关于如何在Tina平台上使用DirectFB,请参考失之东榆,收之桑榆,东方不亮西方亮,活人不能让尿憋死,VIPP虽然不给力,但我们还有VPU(VE),VE支持支持画框和贴水印的操作,画框VIPP已经干......
  • AOP的概念
    AOP为AspectOrientedProgramming的缩写,意为:面向切面编程。AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构。利用AOP可以对业务逻辑的各个部分进行隔离,从而使......
  • proto-buf模型格式测试一例
    本文是在这篇博客的基础上开发一个简单的数据模型,在模型上进行序列化和反序列化操作,并检验数据的正确性。1.编写数据格式描述文件需要注意的是,为了增加难度,我定义了具有嵌套......
  • 验证darknet中前处理做图像缩放(双线性内插值法)scale的算法效果
    ​​DARKNET中使用的缩放算法是双线性内插值法,这里就实际验证一把DARKNET中scale的工作原理与效果:首先这是一张原图,画面中的是南京明城墙玄武门,玄武湖的正门。18年国庆带娃......
  • OpenCL编程之二
    白嫖来的C端代码:matrix.c:#include<stdio.h>#include<stdlib.h>#include<alloca.h>#include<CL/cl.h>#pragmawarning(disable:4996)intmain(){cl_interror;......
  • WPF之深入浅出话事件
    就像属性系统在WPF中得到了升级、进化为依赖属性一样,事件系统在WPF也得到了升级-----进化成为了路由事件(RoutedEvent),并在其基础上衍生出命令传递机制。这些机制在很大程度......
  • 贝尔宾团队角色理论
    ​​剑桥​​​产业培训研究部前主任贝尔宾博士和他的同事们经过多年在​​澳洲​​​和​​英国​​​的研究与实践,提出了著名的贝尔宾团队角色理论,即一支结构合理的团队应......