加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python之面向对象

发布时间:2020-12-16 23:55:49 所属栏目:Python 来源:网络整理
导读:table style="height: 30px; width: 1132px; background-color: #afeeee; ; width: 1132px;" border="0" tr td span style="font-size: 16px;"一、面向对象基础 /td /tr /table 本文主要介绍python中的面向对象,分为面向对象基础和面向对象进阶。 编程范式
<tr>
<td><span style="font-size: 16px;">一、面向对象基础</td>
</tr></table>

  本文主要介绍python中的面向对象,分为面向对象基础和面向对象进阶。

编程范式

编程是程序员用特定的语法+数据结构+算法组成的代码来告诉计算机如何执行任务的过程 ,一个程序是程序员为了得到一个任务结果而编写的一组指令的集合,正所谓条条大路通罗马,实现一个任务的方式有很多种不同的方式, 对这些不同的编程方式的特点进行归纳总结得出来的编程方式类别,即为编程范式。 不同的编程范式本质上代表对各种类型的任务采取的不同的解决问题的思路, 大多数语言只支持一种编程范式,当然也有些语言可以同时支持多种编程范式。 两种最重要的编程范式分别是

python编程范式:

1.面向过程:根据业务逻辑从上到下写代码

2.函数式编程:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

3.面向对象:对函数进行分类和封装,让开发“更快更好更强...”

面向对象编程

OOP编程(Object Oriented Programming )是利用“类”和“对象”来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

面向对象的几个核心特性如下:

Class 类一个类即是对一类拥有相同属性的对象的抽象、蓝图、原型。在类中定义了这些对象的都具备的属性(variables(data))、共同的方法

Object 对象?一个对象即是一个类的实例化后的实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人是指具体的对象,人与人之前有共性,亦有不同

Encapsulation 封装在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊或容器,里面包含着类的数据和方法

Inheritance 继承一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承

Polymorphism 多态多态是面向对象的重要特性,简单点说:“一个接口,多种实现”,指一个基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。

类的定义

Foo: (self,name,age): self.name==(%obj1=Foo(<span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">',22)<span style="color: #008000;">#<span style="color: #008000;">类的实例化
obj1.bar()<span style="color: #008000;">#
<span style="color: #008000;">调用对象中的方法

python中类的三大特性

  • 封装
  • 继承
  • 多态

封装:对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。

例如:

==(%

obj1=person(<span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">',22)<span style="color: #008000;">#<span style="color: #008000;">将wd和22封装到obj1的name,age中,调用的时候可以通过obj1.name和obj1.age来调用

继承:面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”。被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。继承又可以分为单继承和多继承。

例如:

(<span style="color: #0000ff;">class son(father):<span style="color: #008000;">#<span style="color: #008000;">继承father
<span style="color: #0000ff;">pass
<span style="color: #000000;">

person1=<span style="color: #000000;">father()
person1.print_name()<span style="color: #008000;">#继承<span style="color: #008000;">了father类的print_name方法
<span style="color: #000000;">结果:
this <span style="color: #0000ff;">is father

多态:基类中派生出了不同的子类,且每个子类在继承了同样的方法名的同时又对父类的方法做了不同的实现。

?例如:

<span style="color: #0000ff;">class son1(father):<span style="color: #008000;">#<span style="color: #008000;">继承father类
<span style="color: #0000ff;">def<span style="color: #000000;"> show_name(self):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">son1.name<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">class son2(father):<span style="color: #008000;">#<span style="color: #008000;">继承father类
<span style="color: #0000ff;">def<span style="color: #000000;"> show_name(self):
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">son2.name<span style="color: #800000;">"<span style="color: #000000;">)

<span style="color: #0000ff;">def fun(obj):<span style="color: #008000;">#<span style="color: #008000;">同一接口不同表现
<span style="color: #000000;"> obj.show_name()
jack=<span style="color: #000000;">son1()
mack=<span style="color: #000000;">son2()
fun(jack)
fun(mack)
结果:
son1.name
son2.name

?类的构造方法和析构方法:

构造方法(__init__):类创建对象时,自动触发执行。

析构方法(__del__):当对象在内存中被释放时,自动触发执行,内存释放分为两种,程序结束或者对象被删除的时候。

例如:

<span style="color: #0000ff;">class<span style="color: #000000;"> person:
<span style="color: #0000ff;">def
<span style="color: #800080;">init
<span style="color: #000000;">(self,age):
self.name
=<span style="color: #000000;">name
self.age
=<span style="color: #000000;">age
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">exec init ....<span style="color: #800000;">"<span style="color: #000000;">)

</span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__del__</span><span style="color: #000000;"&gt;(self):
    </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;exec del.....</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;)

a=person(<span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">',22)<span style="color: #008000;">#<span style="color: #008000;">实例化过程,执行init构造方法
<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;">before del obj.....<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">del a <span style="color: #008000;">#<span style="color: #008000;">删除对象内存指针,释放对象内存地址,执行del析构方法
<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;">after del obj.....<span style="color: #800000;">'<span style="color: #000000;">)
结果:
<span style="color: #0000ff;">exec<span style="color: #000000;"> init ....
before <span style="color: #0000ff;">del<span style="color: #000000;"> obj.....
<span style="color: #0000ff;">exec <span style="color: #0000ff;">del<span style="color: #000000;">.....
after <span style="color: #0000ff;">del obj.....

python继承中的构造方法

在Python中子类继承父类的过程中,如果子类不覆盖父类的__init__()方法,则子类默认将执行与父类一样的初始化方法。但是假如子类自己重写了(也成为覆盖)父类的__init__()方法,那么就需要显式的调用父类的初始化方法了。有两种方法可以做到:

1.父类名.__init__() :经典类写法

2.super(子类名,self)__init__():新式类写法,super方法支持调用父类方法,

例如:

多继承中的相同方法寻找顺序

如果一个类继承了继承了多个类,并且父类和子类都具有相同的方法,使用子类方法,若子类中没有该方法,那么寻找方法的顺序是分别是:

根据版本不同,顺序不同。

  • 当类是经典类时,多继承情况下,会按照深度优先方式查找
  • 当类是新式类时,多继承情况下,会按照广度优先方式查找(就近原则,先找上一级,找完在找上上级)

  • 无论是经典类还是新式类都一样,都是按广度优先的方式查找

python3中类的分类:

  • 经典类:定义中未继承object类称为经典类
  • 新式类:继承了object类或者父类继承了object类称为新式类

例如:

总结:

  • 面向对象是一种编程方式,此编程方式的实现是基于对??和?对象?的使用
  • 类 是一个模板,模板中包装了多个“函数”或者属性供使用
  • 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数
  • 面向对象三大特性:封装、继承和多态

<table style="height: 30px; width: 1132px; background-color: #afeeee; ; width: 1132px;" border="0">

<tr>
<td><span style="font-size: 16px;">二、面向对象进阶</td>
</tr></table>
<p align="left">1.类的实例化过程解析

<img src="https://www.52php.cn/res/2019/03-04/13/e12c3c765d28255ccd72673f06850f1d.png" alt="">


<p align="left">步骤1:先申请示例的内存空间


<p align="left">步骤2:将实例的内存地址和参数传递给相应的类


<p align="left">步骤3:执行类的构造方法将参数封装在实例中,示例创建完毕


<p align="left">?


<p align="left">2.类成员详细介绍?


<p align="left">类成员:python3可将类成员分为属性、方法、特殊成员,按所属关系可分为公有成员、私有成员。


<p align="left">属性:属性的调用方式都是通过对象或者类名加点的方式,如:类.属性,对象.属性,属性分为:普通属性、私有属性、公有属性,<span style="color: #ff6600;">公有属性保存在类中,其他保存在对象中。


<p align="left">公有成员:任何地方都能访问。


<p align="left">私有成员:只允许在类的内部访问,定义时候需要加上双下划线。


<p align="left">方法:普通方法、类方法、静态方法、属性方法,<span style="color: #ff6600;">类中的方法都保存在类中。


<p align="left">特殊成员:docdict等,稍后详细介绍。


<p align="left">?


<p align="left"><span style="font-size: 14px; color: #ff6600;">?a、属性


<p align="left">普通属性:普通属性通过类的构造方法得到,并且<span style="color: #ff9900;"><span style="color: #ff6600;">普通属性保存在实例中。


<p align="left">公有属性:定义在类中,并且<span style="color: #ff6600;">公有属性保存在类中,访问公有属性最好通过类访问。


<p align="left">例如:


<p align="left">

<img src="https://www.52php.cn/res/2019/03-04/13/22753b046205b195ae6c0347af47d6f9.png" alt="">


<p align="left">?私有属性:定义私有属性的方法:在属性前加,如self.name=name,私有属性<span style="color: #ff6600;">只允许类的内部访问,对外部不可见,可以通过return方法让外部可见,想要强行访问可用过【<span style="color: #ff6600;">对象._类名__私有属性名】访问。


<p align="left">例如:


<p align="left">

<img src="https://www.52php.cn/res/2019/03-04/13/199ec432b43c089fcde8f568fbd2c9a0.png" alt="">


<p align="left">?


<p align="left"><span style="font-size: 15px; color: #ff6600;">b、方法


<p align="left">普通方法:普通方法就是定义在类中的普通函数。


<p align="left">类方法:由类调用,在普通方法前加上@classmethod,类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量用。


<p align="left">静态方法:由类调用,在方法前加@staticmethod无默认参数(意思类不会传递self或者其他参数,但是可以自己加参数),<span style="color: #ff6600;">其实和普通函数相同,只是调用通过类,如果被装饰的方法含有self参数,调用的时候会当作普通参数处理,而不是当作实例本身。


<p align="left">属性方法:通过@property把一个方法变成一个普通属性,<span style="color: #ff6600;">定义时只传递self参数,调用时和普通属性一样通过<span style="color: #ff6600;">对象.属性的方式调用(相当于一个属性),并且类属性方法无法通过del删除(除了设置了删除方法,后续提到)。


<p align="left">例如:


<p align="left">

<img src="https://www.52php.cn/res/2019/03-04/13/476043c38027587bb2ce87e29e8df19b.png" alt="">


<p align="left">?


<p align="left">类属性方法(property)详细说明:


<p align="left">上面说过了,python类可分为经典类和新式类,相对于经典类而言,新式类(继承object)属性丰富。


<p align="left">经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法。新式类中的属性有三种访问方式,并分别对应了三个被<span style="color: #ff6600;">@property(获取)、@方法名.setter(设置)、@方法名.deleter(删除)修饰的方法,由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除。


<p align="left">?例如:


<p align="left">

<img src="https://www.52php.cn/res/2019/03-04/13/fd26d192ec186de9fc0d98c787bece9e.png" alt="">


<p align="left">?


<p align="left">?property类源码剖析:


<div class="cnblogs_code" onclick="cnblogs_code_show('40aa788e-bb05-4cbc-8dfc-7b510f9cbbde')">
<img id="code_img_closed_40aa788e-bb05-4cbc-8dfc-7b510f9cbbde" class="code_img_closed" src="https://www.52php.cn/res/2019/03-04/13/1c53668bcee393edac0d7b3b3daff1ae.gif" alt=""><img id="code_img_opened_40aa788e-bb05-4cbc-8dfc-7b510f9cbbde" class="code_img_opened" style="display: none;" onclick="cnblogs_code_hide('40aa788e-bb05-4cbc-8dfc-7b510f9cbbde',event)" src="https://www.52php.cn/res/2019/03-04/13/405b18b4b6584ae338e0f6ecaf736533.gif" alt=""><div id="cnblogs_code_open_40aa788e-bb05-4cbc-8dfc-7b510f9cbbde" class="cnblogs_code_hide">

 property attribute
fget is a function to be used for getting an attribute value,and likewise
fset is a function for setting,and fdel a function for del'ing,an
attribute.  Typical use is to define a managed attribute x:

class C(object):
    def getx(self): return self._x
    def setx(self,value): self._x = value
    def delx(self): del self._x
    x = property(getx,setx,delx,"I'm the 'x' property.")

Decorators make defining new properties or modifying existing ones easy:

class C(object):
    @property
    def x(self):
        "I am the 'x' property."
        return self._x
    @x.setter
    def x(self,value):
        self._x = value
    @x.deleter
    def x(self):
        del self._x
</span><span style="color: #800000;"&gt;"""</span>
<span style="color: #0000ff;"&gt;def</span> deleter(self,*args,**kwargs): <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; real signature unknown</span>
    <span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Descriptor to change the deleter on a property. </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;pass</span>

<span style="color: #0000ff;"&gt;def</span> getter(self,**kwargs): <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; real signature unknown</span>
    <span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Descriptor to change the getter on a property. </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;pass</span>

<span style="color: #0000ff;"&gt;def</span> setter(self,**kwargs): <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; real signature unknown</span>
    <span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Descriptor to change the setter on a property. </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;pass</span>

<span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__delete__</span>(self,**kwargs): <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; real signature unknown</span>
    <span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Delete an attribute of instance. </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;pass</span>

<span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__getattribute__</span>(self,**kwargs): <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; real signature unknown</span>
    <span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Return getattr(self,name). </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;pass</span>

<span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__get__</span>(self,**kwargs): <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; real signature unknown</span>
    <span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Return an attribute of instance,which is of type owner. </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;pass</span>

<span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__init__</span>(self,fget=None,doc=None): <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; known special case of property.__init__</span>
    <span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    property(fget=None,doc=None) -> property attribute

    fget is a function to be used for getting an attribute value,and likewise
    fset is a function for setting,an
    attribute.  Typical use is to define a managed attribute x:

    class C(object):
        def getx(self): return self._x
        def setx(self,value): self._x = value
        def delx(self): del self._x
        x = property(getx,"I'm the 'x' property.")

    Decorators make defining new properties or modifying existing ones easy:

    class C(object):
        @property
        def x(self):
            "I am the 'x' property."
            return self._x
        @x.setter
        def x(self,value):
            self._x = value
        @x.deleter
        def x(self):
            del self._x

    # (copied from class doc)
    </span><span style="color: #800000;"&gt;"""</span></pre>

property类构造方法有参数为4个:

  • 第一个参数是方法名,调用?对象.属性?时自动触发执行方法
  • 第二个参数是方法名,调用?对象.属性 = XXX?时自动触发执行方法
  • 第三个参数是方法名,调用?del 对象.属性?时自动触发执行方法
  • 第四个参数是字符串,调用?对象.属性.__doc__?,此参数是该属性的描述信息

= set_name(self,value): self.name=(BAR</span>=property(get_name,set_name,del_name,<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;something</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;)

obj=FOO(<span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">')<span style="color: #008000;">#<span style="color: #008000;">自动调用property中的get_name
<span style="color: #0000ff;">print<span style="color: #000000;">(obj.BAR)
obj.BAR=<span style="color: #800000;">'<span style="color: #800000;">jack<span style="color: #800000;">'<span style="color: #008000;">#<span style="color: #008000;">自动调用第二个参数中的set_name
<span style="color: #0000ff;">print<span style="color: #000000;">(obj.BAR)
<span style="color: #0000ff;">del obj.BAR <span style="color: #008000;">#<span style="color: #008000;">自动调用第三个参数的del_name
<span style="color: #0000ff;">print(FOO.BAR.<span style="color: #800080;">doc)<span style="color: #008000;">#<span style="color: #008000;">自动获取第4个参数中获取的值

python中类特殊成员在类生成时自动生成,大致成员如下:

1.__doc__:类的描述信息

(FOO.

2.__module__ 和 ?__class__?: ?__module__: 表示当前操作的对象在那个模块,__class__ ?表示当前操作的对象的所属类是什么。

(FOO.(FOO. < >

3.__init__:类的构造方法,创建实例时候自动执行。

4.__del__:析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

5.?__call__:对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

(self,**(= call....

6.?__dict__:类或对象中的所有成员,返回是个字典的形式。

= ==</span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__call__</span>(self,**<span style="color: #000000;"&gt;kwargs): </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;exec call....</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;)

obj=FOO(<span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">',22<span style="color: #000000;">)
<span style="color: #0000ff;">print(obj.<span style="color: #800080;">dict<span style="color: #000000;">)
<span style="color: #0000ff;">print(FOO.<span style="color: #800080;">dict<span style="color: #000000;">)
结果:
{<span style="color: #800000;">'<span style="color: #800000;">age<span style="color: #800000;">': 22,<span style="color: #800000;">'<span style="color: #800000;">name<span style="color: #800000;">': <span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">'<span style="color: #000000;">}
{<span style="color: #800000;">'<span style="color: #800000;">weakref<span style="color: #800000;">': <attribute <span style="color: #800000;">'<span style="color: #800000;">weakref<span style="color: #800000;">' of <span style="color: #800000;">'<span style="color: #800000;">FOO<span style="color: #800000;">' objects>,<span style="color: #800000;">'<span style="color: #800000;">dict<span style="color: #800000;">': <attribute <span style="color: #800000;">'<span style="color: #800000;">dict<span style="color: #800000;">' of <span style="color: #800000;">'<span style="color: #800000;">FOO<span style="color: #800000;">' objects>,<span style="color: #800000;">'<span style="color: #800000;">doc<span style="color: #800000;">': <span style="color: #800000;">'<span style="color: #800000;">this foo class<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">CITY<span style="color: #800000;">': <span style="color: #800000;">'<span style="color: #800000;">beijing<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">call<span style="color: #800000;">': <function FOO.<span style="color: #800080;">call at 0x000000000106E268>,<span style="color: #800000;">'<span style="color: #800000;">module<span style="color: #800000;">': <span style="color: #800000;">'<span style="color: #800000;">main<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">init<span style="color: #800000;">': <function FOO.<span style="color: #800080;">init at 0x000000000106E1E0>}

?7.?__str__:如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

= ( obj=FOO(<span style="color: #800000;">'<span style="color: #800000;">wd<span style="color: #800000;">',22<span style="color: #000000;">)
<span style="color: #0000ff;">print
(obj)<span style="color: #008000;">#
<span style="color: #008000;">调用str输出return内容

<span style="color: #000000;">结果:
this
<span style="color: #0000ff;">is
FOO

8.__getitem__、__setitem__、__delitem__:用于索引操作,如字典。以上分别表示获取、设置、删除数据

(</span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__setitem__</span><span style="color: #000000;"&gt;(self,key,value): </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;__setitem__</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,value) </span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__delitem__</span><span style="color: #000000;"&gt;(self,key): </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;__delitem__</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;,key)

obj=<span style="color: #000000;">Foo()
result = obj[<span style="color: #800000;">'<span style="color: #800000;">k1<span style="color: #800000;">'] <span style="color: #008000;">#<span style="color: #008000;"> 自动触发执行 getitem
obj[<span style="color: #800000;">'<span style="color: #800000;">k2<span style="color: #800000;">'] = <span style="color: #800000;">'<span style="color: #800000;">wupeiqi<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 自动触发执行 setitem
<span style="color: #0000ff;">del obj[<span style="color: #800000;">'<span style="color: #800000;">k1<span style="color: #800000;">'] <span style="color: #008000;">#<span style="color: #008000;"> 自动触发执行 delitem

9. __iter__ :用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__

</span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__init__</span><span style="color: #000000;"&gt;(self,sq): self.sq </span>=<span style="color: #000000;"&gt; sq </span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__iter__</span><span style="color: #000000;"&gt;(self): </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; iter(self.sq)

obj = Foo([11,22,33,44<span style="color: #000000;">])

<span style="color: #0000ff;">for i <span style="color: #0000ff;">in<span style="color: #000000;"> obj:
<span style="color: #0000ff;">print<span style="color: #000000;"> (i)
结果:
11
22
33
44

10. __new__ __metaclass__

=obj = Foo(<span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">")

上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的构造方法创建。

print(type(obj)) # 输出: 表示,obj 对象由Foo类创建print (type(Foo)) # 输出: 表示,Foo类对象由 type 类创建

所以,obj对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象是通过type类的构造方法创建。

那么,创建类就可以有两种方式:

1.普通方式:

= name

2.特殊方式(使用type类的构造函数):

(<span style="color: #0000ff;">def<span style="color: #000000;"> func(self):
<span style="color: #0000ff;">print
(<span style="color: #800000;">'
<span style="color: #800000;">name:{}
<span style="color: #800000;">'
<span style="color: #000000;">.format(self.name))

<span style="color: #0000ff;">def <span style="color: #800080;">init<span style="color: #000000;">(self,age):
self.name=<span style="color: #000000;">name
self.age=<span style="color: #000000;">age

Foo = type(<span style="color: #800000;">'<span style="color: #800000;">Foo<span style="color: #800000;">',(person,),{<span style="color: #800000;">'<span style="color: #800000;">func<span style="color: #800000;">': func,<span style="color: #800000;">'<span style="color: #800000;">init<span style="color: #800000;">':<span style="color: #800080;">init<span style="color: #000000;">})
bar=Foo(<span style="color: #800000;">'<span style="color: #800000;">jack<span style="color: #800000;">',22<span style="color: #000000;">)
bar.func()
bar.get_name()
<span style="color: #008000;">#<span style="color: #008000;">第一个参数为类名<span style="color: #008000;">

<span style="color: #008000;">第二个参数为要继承的类名(可以不写,代表不继承某个类)<span style="color: #008000;">

<span style="color: #008000;">第三个参数为方法,格式为{'方法名':方法内存地址}

类 是由 type 类实例化产生

那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

答:类中有一个属性?__metaclass__,其用来表示该类由谁来实例化创建,所以,我们可以为?__metaclass__ 设置一个type类的派生类,从而查看类创建的过程

(self,** </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Mytype __init__</span><span style="color: #800000;"&gt;"</span>,**<span style="color: #000000;"&gt;kwargs) </span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__call__</span>(self,**<span style="color: #000000;"&gt;kwargs): </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Mytype __call__</span><span style="color: #800000;"&gt;"</span>,**<span style="color: #000000;"&gt;kwargs) obj </span>= self.<span style="color: #800080;"&gt;__new__</span><span style="color: #000000;"&gt;(self) </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;obj </span><span style="color: #800000;"&gt;"</span>,obj,**<span style="color: #000000;"&gt;kwargs) </span><span style="color: #0000ff;"&gt;print</span><span style="color: #000000;"&gt;(self) self.</span><span style="color: #800080;"&gt;__init__</span>(obj,**<span style="color: #000000;"&gt;kwargs) </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; obj </span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__new__</span>(cls,**<span style="color: #000000;"&gt;kwargs): </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Mytype __new__</span><span style="color: #800000;"&gt;"</span>,**<span style="color: #000000;"&gt;kwargs) </span><span style="color: #0000ff;"&gt;return</span> type.<span style="color: #800080;"&gt;__new__</span>(cls,**<span style="color: #000000;"&gt;kwargs)

<span style="color: #0000ff;">print(<span style="color: #800000;">'<span style="color: #800000;">here...<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">class Foo(object,metaclass=<span style="color: #000000;">MyType):

</span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__init__</span><span style="color: #000000;"&gt;(self,name):
    self.name </span>=<span style="color: #000000;"&gt; name

    </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Foo __init__</span><span style="color: #800000;"&gt;"</span><span style="color: #000000;"&gt;)

</span><span style="color: #0000ff;"&gt;def</span> <span style="color: #800080;"&gt;__new__</span>(cls,**<span style="color: #000000;"&gt;kwargs):
    </span><span style="color: #0000ff;"&gt;print</span>(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;Foo __new__</span><span style="color: #800000;"&gt;"</span>,cls,**<span style="color: #000000;"&gt;kwargs)
    </span><span style="color: #0000ff;"&gt;return</span> object.<span style="color: #800080;"&gt;__new__</span><span style="color: #000000;"&gt;(cls)

f = Foo(<span style="color: #800000;">"<span style="color: #800000;">wd<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">f<span style="color: #800000;">"<span style="color: #000000;">,f)
<span style="color: #0000ff;">print(<span style="color: #800000;">"<span style="color: #800000;">fname<span style="color: #800000;">"<span style="color: #000000;">,f.name)

<span style="color: #008000;">#<span style="color: #008000;">自定义元类<span style="color: #008000;"># 第一阶段:解释器从上到下执行代码创建Foo类

类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

?metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python?

反射:

通过字符串映射或修改程序运行时的状态、属性、方法,有以下4个方法。

1.getattr(object,default=None):获取属性,返回属性内存地址。

2.hasattr(object,name):判断有无属性,返回True或者Flase。

3.setattr(x,y,v):设置属性,x.y=v

4.delattr(x,y):删除属性

示例:

=
<span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; func(self):
    </span><span style="color: #0000ff;"&gt;return</span> <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;func</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;

obj =<span style="color: #000000;"> Foo()

<span style="color: #008000;">#<span style="color: #008000;">#### 检查是否含有成员 ####
hasattr(obj,<span style="color: #800000;">'<span style="color: #800000;">name<span style="color: #800000;">'<span style="color: #000000;">)
hasattr(obj,<span style="color: #800000;">'<span style="color: #800000;">func<span style="color: #800000;">'<span style="color: #000000;">)

<span style="color: #008000;">#<span style="color: #008000;">#### 获取成员 ####
getattr(obj,<span style="color: #800000;">'<span style="color: #800000;">name<span style="color: #800000;">'<span style="color: #000000;">)
getattr(obj,<span style="color: #800000;">'<span style="color: #800000;">func<span style="color: #800000;">'<span style="color: #000000;">)

<span style="color: #008000;">#<span style="color: #008000;">#### 设置成员 ####
setattr(obj,<span style="color: #800000;">'<span style="color: #800000;">age<span style="color: #800000;">',18<span style="color: #000000;">)
setattr(obj,<span style="color: #800000;">'<span style="color: #800000;">show<span style="color: #800000;">',<span style="color: #0000ff;">lambda num: num + 1<span style="color: #000000;">)
setattr(Foo,<span style="color: #800000;">'<span style="color: #800000;">city<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">beijing<span style="color: #800000;">'<span style="color: #000000;">)
<span style="color: #0000ff;">print<span style="color: #000000;">(Foo.city)
<span style="color: #008000;">#<span style="color: #008000;">#### 删除成员 ####
delattr(obj,<span style="color: #800000;">'<span style="color: #800000;">name<span style="color: #800000;">'<span style="color: #000000;">)
delattr(Foo,<span style="color: #800000;">'<span style="color: #800000;">func<span style="color: #800000;">')<span style="color: #008000;">#<span style="color: #008000;">删除类中方法
getattr(Foo,<span style="color: #800000;">'<span style="color: #800000;">func<span style="color: #800000;">')<span style="color: #008000;">#<span style="color: #008000;">报错

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

<table style="height: 30px; width: 1132px; background-color: #afeeee; ; width: 1132px;" border="0">

    推荐文章
      热点阅读