• 手机站
  • 收藏
聚培教育网合作机构 > 呼和浩特达内教育
呼和浩特达内教育
400-998-6158
呼和浩特达内教育开设Java、C++、C#/.Net、 PHP、嵌入式、软件测试、UID、网络营销、Linux云计算、主办会计、UED、WEB前端等课程
呼和浩特达内教育

Python面向对象编程的知识点

python学习网

更新时间:2021-11-04 浏览:152
核心提示:今日将Python面向对象编程的相关内容开展梳理,多方位再跟大伙儿讲解Python面向对象编程,期待可以协助大伙儿全方位把握这方面的专业知识。

以前有跟大伙儿聊起什么叫Python面向对象方法,什么叫Python面向对象编程,及其Python面向对象方法和面向过程的区别,今日将Python面向对象编程的相关内容开展梳理,多方位再跟大伙儿讲解Python面向对象编程,期待可以协助大伙儿全方位把握这方面的专业知识。

面向对象设计和函数式编程(面向对象方法程序编写)全是程序流程设计的方法,但是稍有差别。

面向对象方法程序编写:


1. 导进各种各样外界库

2. 设计方案各种各样局部变量

3. 写一个涵数进行某一作用

4. 写一个涵数进行某一作用

5. 写一个涵数进行某一作用

6. 写一个涵数进行某一作用

7. 写一个涵数进行某一作用

8. ......

9. 写一个main函数做为程序流程通道

在多涵数程序流程中,很多主要的信息被安装在全局性数据信息区,那样他们可能被大部分的涵数浏览。每一个涵数都能够具备他们自身的部分数据信息,将一些作用编码封裝到涵数中,日后便不用反复撰写,仅函数调用就可以。从编码的组织结构看来便是依据领域模型从上向下垒编码 。

面向对象设计:


1. 导进各种各样外界库

2. 设计方案各种各样局部变量

3. 决策你需要的类

4. 给每一个类给予详细的一组实际操作

5. 确立地应用承继来主要表现不一样类中间的相同点

6. 依据*须 ,决策是不是写一个main函数做为程序流程通道

面向对象设计中,将涵数和自变量进一步封裝成类,类才算是程序流程的基本元素,它将数据库和实际操作密切地相互连接在一起,并维护信息不容易被外部的涵数出现意外地更改。类和和类的案例(也称目标)是面向过程的关键定义,是和面向对象方法程序编写,函数式编程的压根差别。

并没有一定要用面向对象设计,需看你的程序流程怎么设计便捷,可是就现在而言,大部分是在应用面向对象设计。

类的一般使用方法

面向对象编程是根据界定class类来界定,那么说面向对象设计便是只应用class类,在class类中有封裝,承继的作用,而且还能够结构要传到的主要参数,便捷操纵。

实例一


import sys
import time
reload(sys)
sys.setdefaultencoding('utf-8')

class studetn:
    # 界定一个类名叫studetn
    def ._init._(self,idx):
    # 界定复位结构,这儿应用init,也有其他特性例如reversed,iter这类的
        self.idx=idx
        # 复位自变量,便捷承继
    def runx(self):
    # 界定运作涵数,从上边承继自变量
        print self.idx
        # 打印出出idx的值,或是做一些其他解决
        time.sleep(1)
a=studetn('a')
a.runx()
# 这也是类的启用,一定要还记得类的操作方法,*传到主要参数,类取值给一个自变量a
# 随后启用这一类下边界定的涵数

一些专业名词定义,即然有面向对象设计这一高逼格的概念了,当然要配搭一些高端大气的定义。

类(Class): 用于叙述具备同样特性和方式 的另一半的结合。它界定了该结合中每一个目标所现有的特性和方式 。在其中的目标称之为类的案例。

案例:也称目标。根据类界定的复位方式 ,授予实际的值,变成一个”平凡而不平庸的实体线”。

创建对象:建立类的案例的方式或实际操作。

实例变量:界定在案例中的自变量,只功能于当今案例。

类自变量:类自变量是全部案例公有制的自变量。类变量定义在类中,但在方式 体以外。

数据信息组员:类自变量,实例变量,方式 ,类方法,静态方法和状态等的通称。

方式 :类中界定的涵数。

静态方法:不用创建对象就可以由类实行的方式

类方法:类方法是将类自身做为目标开展实际操作的方式 。

方式 调用:假如从父类承继的方案无法达到派生类的要求,能够对父类的方式 开展改变,这一环节也称override。

封裝:将內部完成包囊起來,对外开放全透明,给予api接口开展调节的体制

承继:即一个派生类(derived class)承继父类(base class)的自变量和方式 。

java多态:依据目标种类的不一样以不一样的方法实现解决。

类与案例


# -*- coding: utf-8 -*-
# @Time    : 2018/5/3 0003 17:02
# @Author  : Langzi
# @Blog    : www.langzi.fun
# @File    : 面向对象编程2.py
# @Software: PyCharm
import sys
import time
import requests
reload(sys)
sys.setdefaultencoding('utf-8')

class cc:
    ccc = 'ccc'
    # cc便是类名 假如要想承继其他类 就class cc(threading) 含意就是以threading承继
    def ._init._(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c
        # 界定结构的历程便是创建对象
    def runx(self):
        print self.a*10
        print self.b*5
        print self.c*2
    def runy(self):
        print requests.get('http://www.langzi.fun').headers
e = cc('AAA','CCC','EEE')
e.runx()
e.runy()
# 这两个便是启用类里边的方式 
print e.c
#实例变量指的是案例自身具有的自变量。每一个例子的自变量在运行内存上都不一样。
print e.ccc
#类自变量,在类里边寻找界定的自变量。

启用类的三种方式

实例方法


# -*- coding: utf-8 -*-
# @Time    : 2018/5/3 0003 17:16
# @Author  : Langzi
# @Blog    : www.langzi.fun
# @File    : 面向对象编程3.py
# @Software: PyCharm
import sys
import time
import requests
reload(sys)
sys.setdefaultencoding('utf-8')

class dd:
    def ._init._(self,url):
        self.url=url
    def runx(self):
        print requests.get(self.url).status_code

a = dd('http://www.langzi.fun')
a.runx()
# 这类启用方式 便是实例方法

静态方法

静态方法由类启用,无默认设置主要参数。将实例方法主要参数中的self除掉,随后在方式 界定上边再加上@staticmethod,就变成静态方法。它归属于类,和案例不相干。提议只应用类名.静态方法的获取方法。(尽管可以应用实例名.静态方法的方法启用)


# -*- coding: utf-8 -*-
# @Time    : 2018/5/3 0003 17:21
# @Author  : Langzi
# @Blog    : www.langzi.fun
# @File    : 面向对象编程4.py
# @Software: PyCharm
import sys
import requests
reload(sys)
sys.setdefaultencoding('utf-8')
class ff:
    @staticmethod
    def runx():
        print requests.get('http://www.langzi.fun').status_code
ff.runx()
#这儿就立即启用了类的自变量,只在类中运作而没有案例中使用的方式 

常常有一些跟类有关系的作用但在操作时又不用案例和类参加的情形下须要使用静态方法. 例如变更系统变量或是改动别的类的特性等能使用静态方法.这类状况还可以同时用涵数处理, 但那样一样会蔓延类內部的编码,导致维护保养艰难。

类方法

类方法由类启用,选用@classmethod装饰设计,最少传到一个cls(代指类自身,相近self)主要参数。实行类方法时,全自动将启用该方式 的类取值给cls。提议只应用类名.类方法的获取方法。(尽管可以应用实例名.类方法的方法启用)

具体实例

假如要构建一个类,接纳一个网站和一个平台的状态码,随后复印出去。如同那样:


import sys
import requests
reload(sys)
sys.setdefaultencoding('utf-8')
class gg:
    def ._init._(self,url,stat):
        self.url=url
        self.stat=stat
    def outer(self):
        print self.url
        print self.stat
a = gg('langzi',200)
a.outer()

那样便是应用实例方法,尽管可以完成,可是有的情况下传到的技术参数并并不是(‘langzi’,200)那样的文件格式,只是(‘langzi-200’)那样的,那该怎么做?*要把这个分拆,可是要应用实例方法完成起來很不便,这个时候就可以应用类方法。


# -*- coding: utf-8 -*-
# @Time    : 2018/5/3 0003 17:27
# @Author  : Langzi
# @Blog    : www.langzi.fun
# @File    : 面向对象编程5.py
# @Software: PyCharm
import sys
import requests
reload(sys)
sys.setdefaultencoding('utf-8')
class gg:
    url = 0
    stat = 0
    # 由于应用classmethod之后传到新的自变量,因此一开始是*须 个人先界定类自变量
    def ._init._(self,url=0,stat=0):
    # 这儿依照常规的界定构造方法
        self.url=url
        self.stat=stat
    @classmethod
    # 装饰器,立刻实行接下来的涵数
    def split(cls,info):
        # 这一涵数接纳2个主要参数,默认设置的cls就是这个类的init涵数,info便是外边传到进去的
        url,stat=map(str,info.split('-'))
        # 这儿转化成了恢复出厂设置的构造
        data = cls(url,stat)
        # 随后实行这一类**个方式 ,这一类构造方法*须 传到2个主要参数,因此就传到了2个主要参数
        return data
        # 这儿就立即回到了涵数結果
    def outer(self):
        print self.url
        print self.stat

r = gg.split(('langzi-200'))
r.outer()
# 这儿是启用类方法,与启用实例方法一样

类的特点

封裝

封裝就是指将信息与具体步骤的完成编码放到某一目标內部,外界无法打开。务必要先启用类的办法才可以运行。

实例


class cc:
    ccc = 'ccc'
    # cc便是类名 假如要想承继其他类 就class cc(threading) 含意就是以threading承继
    def ._init._(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c
print e.ccc
#类自变量,在类里边寻找界定的自变量。
print ccc
# 这儿会出错,这就是封裝。类中的涵数同样。

承继

在我们界定一个class的情况下,能够从某一目前的class承继,新的class称之为派生类(Subclass),而被承继的class称之为基类,父类或超类(Base class,Super class)。

例如,大家早已制定了一个名叫Animal的class,有一个run()方式 就可以立即打印出:


class Animal(object):
    def run(self):
        print 'Animal is running...'

在我们*须 撰写Dog和Cat类时,就可以立即从Animal类承继:


class Dog(Animal):
    pass
class Cat(Animal):
    pass

承继有哪些好处呢?较大的益处是派生类得到了父类的所有作用。因为Animial完成了run()方式 ,因而,Dog和Cat做为它的派生类,啥事也没干,就全自动存在了run()方式 :


dog = Dog()
dog.run()
cat = Cat()
cat.run()

当派生类和父类都具有相等的run()方式 时,大家说,派生类的run()遮盖了父类的run(),在程序执行的情况下,一直会启用派生类的run()。那样,大家就得到了承继的另一个益处:java多态。

java多态

要了解java多态的益处,大家还*须再撰写一个涵数,这一涵数接纳一个Animal种类的自变量:


def run_twice(animal):
    animal.run()
    animal.run()

在我们传到Animal的案例时,run_twice()就打印出出:


run_twice(Animal())
运作結果:
Animal is running...
Animal is running...

在我们传到Dog的案例时,run_twice()就打印出出:


run_twice(Dog())
运作結果:
Dog is running...
Dog is running...

在我们传到Cat的案例时,run_twice()就打印出出:


run_twice(Cat())
运作結果:
Cat is running...
Cat is running...

看起来没什么意思,可是认真想一想,如今,如果我们再界定一个Tortoise种类,也从Animal继承:


class Tortoise(Animal):
    def run(self):
        print 'Tortoise is running slowly...'

在我们启用run_twice()时,传到Tortoise的案例:


run_twice(Tortoise())
运作結果:
Tortoise is running slowly...
Tortoise is running slowly...

你能发觉,增加一个Animal的派生类,无须对run_twice()做任何的改动,事实上,一切依靠Animal做为参考的涵数或是方式 都能够不用改动地正确运作,缘故就取决于java多态。

java多态的优势便是,在我们*须 传到Dog,Cat,Tortoise……时,大家只要接受Animal种类就可以了,由于Dog,Cat,Tortoise……全是Animal种类,随后,依照Animal种类开展实际操作就可以。因为Animal种类有run()方式 ,因而,传到的随意种类,只需是Animal类或是派生类,便会全自动启用具体种类的run()方式 ,这就是java多态的含意:

针对一个自变量,大家只*须 了解它是Animal种类,不用准确地了解它的子种类,就可以安心地启用run()方式 ,而实际启用的run()方式 是角色在Animal.Dog.Cat或是Tortoise目标上,由运作时该目标的准确种类决策,这就是java多态真真正正的杀伤力:启用方只要启用,无论关键点,而在我们增加一种Animal的派生类时,只需*run()方式 撰写恰当,无需管原先的编码是怎样加载的。这就是有名的“启闭”标准:

对拓展对外开放:容许增加Animal派生类;

对改动封闭式:不用改动依靠Animal种类的run_twice()等涵数。

汇总:承继能够把父类的全部作用都立即拿过来,那样就无须重零开始做起,派生类只*须 增加自身特殊的方式 ,还可以把父类不宜的方式遮盖调用;

拥有承继,才可以有java多态。在启用类实例方法的情况下,尽可能把自变量看作父类种类,那样,全部派生类种类都能够一切正常被接受;

旧的形式界定Python类容许不从object类承继,但这类程序编写方法早已明显不建议应用。任何时刻,要是没有适合的类能够承继,就承继自object类。

法术方式

在上面有提及除开init以外也有iter,reverse的方式 ,这儿就具体说下除开init复位还有哪些其他方式 。


._init._ :      构造方法,在转化成目标时启用
._del._ :       析构函数,释放出来目标时应用
._repr._ :      打印出,变换
._setitem._ :   依照数据库索引取值
._getitem._:    依照数据库索引获得值
._len._:        得到长短
._cmp._:        较为计算
._call._:       启用
._add._:        加计算
._sub._:        减计算
._mul._:        乘计算
._div._:        除计算
._mod._:        求余运算
._pow._:        幂

实际应用

1. doc

描述性文本文档和信息内容。Python建造,不用自定。


class Foo:
    """ 叙述类信息内容,可被全自动搜集 """
    def func(self):
        pass
# 打印出类的详细说明文本文档 
print(Foo.._doc._)

2. init()

创建对象方式 ,根据类建立案例时,全自动开启实行。


class Foo:
    def ._init._(self, name):
        self.name = name
        self.age = 18
obj = Foo(jack') # 全自动实行类中的 ._init._ 方式 

3. module._ 和 ._class

module 表明当今使用的目标在归属于哪一个控制模块。

class 表明当今使用的目标归属于哪一个类。

这两者之间也是Python內建,不用自定。


class Foo:
    pass
obj = Foo()
print(obj.._module._)
print(obj.._class._)
运作結果:
main

4. del()

析构方式 ,当目标在存储空间中被使用时,全自动开启此方式 。

注:此方式 一般不必自定,由于Python内置内存分配和释放出来体制,除非是你需要在放出的情况下特定做一些姿势。析构函数的启用是由编译器在开展垃圾分类回收时全自动开启实行的。


class Foo:
    def ._del._(self):
        print("把我回收利用了!")

obj = Foo()
del obj

5. call()

假如为一个类撰写了该方式 ,那麼在此类的案例后边加括弧,可会启用这一方式 。

注:构造函数的实行是由类加括弧实行的,即:目标 = 类名(),而针对call() 方式 ,是由目标后加括弧开启的,即:目标() 或是 类()()


class Foo:
    def ._init._(self):
        pass
    def ._call._(self, *args, **kwargs):
        print('._call._')
obj = Foo()     # 实行 ._init._
obj()       # 实行 ._call._

可以用Python內建的callable()涵数开展检测,分辨一个目标是不是能够强制执行。


callable(Student())

运作結果:


True

6. dict

列举类或目标中的任何组员!十分必要和有价值的一个特性,Python建造,不用客户我们界定。


class Province:
    country = 'China'
    def ._init._(self, name, count):
        self.name = name
        self.count = count
    def func(self, *args, **kwargs):
        print('func')
# 获得类的组员
print(Province.._dict._)
# 获得 目标obj1 的组员 
obj1 = Province('HeBei',10000)
print(obj1.._dict._)
# 获得 目标obj2 的组员 
obj2 = Province('HeNan', 3888)
print(obj2.._dict._)

7. str()

假如一个类中界定了str()方式 ,那麼在打印出目标时,默认设置輸出该方式 的传参。这也是一个十分关键的方式 ,*须 我们我们界定。

下边的类,沒有界定str()方式 ,打印出結果是:


class Foo:
    pass
obj = Foo()
print(obj)
界定了._str._()方式 后,打印出結果是:'jack'。
class Foo:
    def ._str._(self):
        return 'jack'
obj = Foo()
print(obj)

8.getitem._()._setitem_().._delitem()

选值.取值.删掉这“三剑客”的招数,在Python中,大家早已见过很数次了,例如之前的@property装饰器。

Python中,标志符后边加圆括号,一般意味着实行或启用方式 的含意。而在标志符后边加中括号[],一般意味着取值的意思。Python设计方案了getitem().setitem().delitem()这三个独特组员,用以完成与中括号相关的姿势。他们各自表明选值.取值.删掉数据信息。

也就是如下所示的实际操作:


a = 标志符[] :  实行._getitem._方式 
标志符[] = a  :  实行._setitem._方式 
del 标志符[] :  实行._delitem._方式 

假如有一个类与此同时界定了这三个法术方式 ,那麼这一类的案例的表现看上去就是一个词典一样,如下所示例所显示:


class Foo:
    def ._getitem._(self, key):
        print('._getitem._',key)
    def ._setitem._(self, key, value):
        print('._setitem._',key,value)
    def ._delitem._(self, key):
        print('._delitem._',key)
obj = Foo()
result = obj['k1']      # 全自动开启实行 ._getitem._
obj['k2'] = 'jack'      # 全自动开启实行 ._setitem._
del obj['k1']             # 全自动开启实行 ._delitem._

9. iter()

这也是迭代器方式 !目录.词典.元组往往能够开展for循环,是由于其內部界定了 iter()这一方式 。假如客户想让自定的类的目标能够被迭代更新,那麼就*须在类中界定这一方式 ,而且让该方式 的传参是一个可迭代更新的目标。当在编码中运用for循环遍历对象时,便会启用类的这一iter()方式 。

一般的类:


class Foo:
    pass
obj = Foo()
for i in obj:
    print(i)
# 出错:TypeError: 'Foo' object is not iterable
# 缘故是Foo目标不能迭代更新
加上一个._iter._(),但任何东西都不回到:
class Foo:
    def ._iter._(self):
        pass
obj = Foo()
for i in obj:
    print(i)
# 出错:TypeError: iter() returned non-iterator of type 'NoneType'
#缘故是 ._iter._方式 沒有回到一个可迭代更新的目标

回到一个个迭代更新目标:


class Foo:
    def ._init._(self, sq):
        self.sq = sq
    def ._iter._(self):
        return iter(self.sq)
obj = Foo([11,22,33,44])
for i in obj:
    print(i)

**是的办法是应用制作器:


class Foo:
    def ._init._(self):
        pass
    def ._iter._(self):
        yield 1
        yield 2
        yield 3
obj = Foo()
for i in obj:
    print(i)

10.len()

在Python中,假如你启用内嵌的len()涵数尝试获得一个目标的长短,在后台管理,实际上是去启用该目标的len()方式 ,因此,下边的编码是等额的的:


len('ABC')
3
'ABC'.._len._()
3

Python的list.dict.str等内嵌基本数据类型都完成了该方式 ,可是你自己设计的类要完成len方式 *须 合理设计方案。

11. repr()

这一办法的功效和str()很像,二者的差异是str()回到客户见到的字符串数组,而repr()回到软件开发者见到的字符串数组,换句话说,repr()是为调节工作的。一般二者编码一样。


class Foo:
    def ._init._(self, name):
        self.name = name
    def ._str._(self):
        return "this is %s" % self.name
    ._repr._ = ._str._

12. add._: 加计算 _sub_: 减计算 _mul_: 乘计算 _div_: 除计算 _mod_: 求余运算 ._pow: 幂运算

这种全是算术运算方式 ,想要你自身为类设计方案实际计算编码。有一些Python内嵌基本数据类型,例如int就含有这种方式 。Python适用操作符的轻载,也就是调用。


class Vector:
   def ._init._(self, a, b):
      self.a = a
      self.b = b
   def ._str._(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   def ._add._(self,other):
      return Vector(self.a   other.a, self.b   other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1   v2)

13. author创作者信息内容


._author._ = "Jack"
def show():
    print(._author._)
show()

14. slots

Python成为一种动态语言,能够在类界定进行和创建对象后,给类或是目标再次加上随便数量或是随意种类的变量值或方式 ,这也是动态语言的特点。比如:


def print_doc(self):
    print("haha")

class Foo:
    pass

obj1 = Foo()
obj2 = Foo()
# 动态性加上实例变量
obj1.name = "jack"
obj2.age = 18
# 动态性的给类加上实例方法
Foo.show = print_doc
obj1.show()
obj2.show()

可是!假如我觉得限定案例能够调用的自变量该怎么办?能够使slots限定案例的自变量,例如,只容许Foo的案例加上name和age特性。


def print_doc(self):
    print("haha")
class Foo:
    ._slots._ = ("name", "age")
    pass
obj1 = Foo()
obj2 = Foo()
# 动态性加上实例变量
obj1.name = "jack"
obj2.age = 18
obj1.sex = "male"       # 这一句会弹出来不正确
# 可是没法限定给类加上方式 
Foo.show = print_doc
obj1.show()
obj2.show()
因为'sex'没有._slots._的方式中,因此不可以关联sex特性,尝试关联sex将获得AttributeError的不正确。
Traceback (most recent call last):
  File "F:/Python/pycharm/201705/1.py", line 14, inobj1.sex = "male"
AttributeError: 'Foo' object has no attribute 'sex'

*须 提示的是,slots界定的特性仅对当今类的案例起功效,对承继了它的派生类是失灵的。想想也是这种大道理,假如你承继一个父类,却无缘无故发觉有一些自变量无法定义,那不是问题么?假如非得派生类也被限定,除非是在派生类中也界定slots,那样,派生类案例容许界定的特点便是本身的slots再加上父类的slots。

组员维护与浏览体制

有一些目标你不想外界浏览,即便 是根据启用类目标也无法打开,那么就请用心学完结章节目录。

独享组员


class obj:
    def ._init._(self,name):
        self.name=name
    def pri(self):
        print self.name
    ._age = 18
    # 再加上双下横线的便是独享自变量,只有在类的內部浏览,外界无法打开
a = obj('zhao')
a.pri()

运作結果:


zhao

假如要在类中获取这一独享组员,能够那么用


class obj:
    def ._init._(self,name):
        self.name=name
    def prin(self):
        print self.name
    ._age = 18
    # 再加上双下横线的便是独享自变量,只有在类的內部浏览,外界无法打开
    @classmethod
    # 假如要在类中启用,*启用类方法
    def pri(cls):
        print cls.._age
        # 随后在应用
a = obj('zhao')
a.prin()
obj.pri()
# 根据那样立即启用类中的独享自变量

运作結果:


zhao
18

应用get-set-del方式 实际操作独享组员


class obj:
    def ._init._(self,name):
        self.name=name
    def prin(self):
        print self.name
    ._age = 18
    # 再加上双下横线的便是独享自变量,只有在类的內部浏览,外界无法打开
    @classmethod
    # 假如要在类中启用,*启用类方法
    def pri(cls):
        print cls.._age
        # 随后在应用
    @classmethod
    def set_age(cls,value):
        cls.._age = value
        return cls.._age
        # 这一使用方法便是更改._age的值
    @classmethod
    def get_age(cls):
        return cls.._age
        # 这一使用方法便是立即回到._age的值
    @classmethod
    def del_age(cls):
        del cls.._age
        # 这一使用方法便是可以删掉._age的值

print obj.get_age()
# 这儿是立即启用出._age的值  传参18
print obj.set_age(20)
# 这儿是立即更改._age的值  传参20
obj.del_age()
# 这儿是立即删掉._age的值

思索:即然是独享自变量,不许外界浏览,为什么有要在后面启用又更改呢?由于需要对独享自变量开展附加的检验,解决,生产加工这些。例如分辨value的值,应用isinstance随后做if-else分辨。

应用独享自变量能够对內部自变量开展维护,外界没法更改,可是能够对它来进行检查解决。

这儿延伸一下独享组员的维护体制,应用._age对独享自变量实际上是—>obj._obj._age的模样开展维护,简言之你同时应用obj._obj._age就可以立即启用內部独享自变量age了。

Propety装饰器

把类的方式 装扮成特性启用的方法,便是把类里边的一个涵数,变为一个特性一样的物品~

一开始启用类的办法要应用圆括号,如今变成了特性开展载入设定储存。

举个案例来表明:

常见的启用方式


class obj:
    def ._init._(self,name,age):
        self.._name=name
        self.._age=age
        # 讲这种设成独享自变量
    def get_age(self):
        return self.._age
    def set_age(self,value):
        if isinstance(value,int):
            self.._age=value
        else:
            raise ValueError('非整数金额种类')
    def del_age(self):
        print 'delete over'
a = obj('langzi',18)
print a.get_age()
a.set_age(20)
print a.get_age()

应用装饰器


class obj:
    def ._init._(self,name,age):
        self.._name=name
        self.._age=age
        # 把这种设成独享自变量
    @property
    def age(self):
        return self.._age
    @age.setter
    def age(self,value):
        if isinstance(value,int):
            self.._age=value
        else:
            raise ValueError('非整数金额种类')
    @age.deleter
    def age(self):
        print 'delete over'
a = obj('langzi',18)
# 应用这种装饰器,能够应用类与对方的办法立即启用
print a.age
# 这儿便是立即启用回到age的值
a.age=20
# 这儿便是可以直接应用setter把值变换
print a.age
del a.age
# 删掉age

自然这类启用方式 有一些不便,每一次全是一个一个去案例类与目标,有一个更为简易直接的方式 。

更为递减的应用property()涵数

不仅应用装饰器的形式将一个方式 装扮成特性外,Python内嵌的builtins控制模块中的property()涵数,为大家出示了第二种设定类特性的方式。


class People:

    def ._init._(self, name, age):
        self.._name = name
        self.._age = age

    def get_age(self):
        return self.._age

    def set_age(self, age):
        if isinstance(age, int):
            self.._age = age
        else:
            raise ValueError

    def del_age(self):
        print("删掉年纪数据信息!")

    # 关键在这一句
    age = property(get_age, set_age, del_age, "年纪")    


obj = People("jack", 18)
print(obj.age)
obj.age = 19
print("obj.age:  ", obj.age)
del obj.ag

根据句子age = property(get_age, set_age, del_age, “年纪”)将一个方式 掩藏变成特性。其实际效果和装饰器的办法是一样的。

property()涵数的主要参数:


**个主要参数是方式 名,启用 案例.特性 时系统自动运行的方式 
第二个因素是方式 名,启用 案例.特性 = XXX时系统自动运行的方式 
第三个主要参数是方式 名,启用 del 案例.特性 时系统自动运行的方式 
第四个主要参数是字符串数组,启用 案例.特性.._doc._时的详情信息内容。

假如你也想新手入门高*职位Python人工智能技术领域,欢迎您来抵达内学习。

感谢你们的阅读文章,之上即是推荐给大伙儿的Python面向对象编程的相关内容,你掌握了没有?大量Python有关的专业知识尽在达内教育Python培训学校官方网站,敬请期待!


更多>同类资讯
更多>相关课程
顶部