首页 后端开发 Python教程 python学习之面向对象编程特性(二)

python学习之面向对象编程特性(二)

Apr 01, 2017 pm 01:34 PM
python 编程 面向对象

面向对象程序设计中的术语对象(Object)基本上可以看做数据(特性)以及由一系列可以存取、操作这些数据的方法所组成的集合。传统意义上的“程序=数据结构+算法”被封装”掩盖“并简化为“程序=对象+消息”。对象是类的实例,类的抽象则需要经过封装。封装可以让调用者不用关心对象是如何构建的而直接进行使用。

首先说明一下python编程规范:

#!/usr/bin/env python
#coding=utf-8
#编程规范,示例如下:
 
class ClassName(object):
       '''testdoc         #这里面是一些说明文档,该类的说明信息是可以被help看到的
              example:
       '''
       #注释的写法,可以在后面,也可以在上一行,单行注释以#号开头
       a= 100          #this is a number for a
       #thisis a number for b
       b= 200
       c= ['a','b']   #or 分行写
       d= {                                   #列表、字典等可以分行写,这样更加直观
                     'key1':'v1',
                     'key2':'v2',
                     'key3':'v3'
       }
 
       def__init__(self,num,m):                   #初始化方法。如果不写,则是从基类继承
              self.age= num
              self.__money= m
 
       deftest(self):
              return100
 
       def__eq__(self,other):                 #魔术方法
              returnself.age == other.age
 
       def__del__(self):   #析构函数,在整个类调用执行完后会执行
              print'world'
 
d = Hello(2,200)
d2 = Hello(3,100)
 
print d == d2         #会自动调用__eq__方法,返回比较结果
 
print d
print d2
登录后复制



书写规范一般从 说明文、初始化方法、单行或多行注释等

一、构造方法:

下面示例说明了构造方法和初始化方法的执行顺序:

#!/usr/bin/env python
 
class Of(object):
 
       def __new__(cls,*args,**kwargs):               #构造方法
                print 'new'
                return super(Of,cls).__new__(cls,*args,**kwargs)
                #returnobject.__new__(cls,*args,**kwargs)
 
       def __init__(self):                #初始化方法
                print "init"
 
       def test(self):
                print 'hello'
 
f = Of()
登录后复制

执行结果如下:

new
init
登录后复制

说明了类在实例化时会先执行构造方法,再去执行初始化方法

下面的示例说明了构造方法和初始化方法的区别:

#!/usr/bin/env python
 
class Resource(object):                 #父类的定义
       def __init__(self):                #初始化方法,为了说明这里直接输出名字
                print 'call me resource init'
 
       def __new__(cls,*args,**kwargs):               #构造方法,这里使用这种传参可以接受任何类型的参数
                print "resource new"
                returnobject.__new__(cls,*args,**kwargs)         #返回值为object基类的构造方法的返回值
 
class DockerResource(Resource):         #子类的定义,继承了Resource类
       def __new__(cls,*args,**kwargs):               #重新构造自己的构造方法
                print "call me dockerresource new"
                returnResource.__new__(cls,*args,**kwargs)            #返回值为Resource父类的构造方法的返回值
 
 
       def __init__(self):                #定义自己的初始化方法
                print 'call docker resourceinit'
 
       def test(self):                #定义test方法
                print 'dosker resource test'
 
r = DockerResource()                  #实例化DockerResource,并将返回值传递给r
print r                          #打印r,查看返回值是什么
print type(r)                  #查看r的类型
r.test()
登录后复制

输出结果如下:

call me docker resource new                #首先调用了DockerResource的构造方法
resource new                                      #构造方法返回的是Resource的构造方法,所以会执行Resource父类构造方法的print "resource new"
call docker resource init                      #然后会执行自己的初始化方法
<__main__.DockerResource object at0x7fa1a3edcf90>             #r现在接受的是Resource父类的构造方法的返回值,所以会有object出现
<class &#39;__main__.DockerResource&#39;>                    #类型为自己DockerResource
dosker resource test                                   #调用自己的test方法
登录后复制

在类中,首先会执行自己的构造方法,如果没有就会从父类继承,然后会执行自己的初始化方法,没有还是会从父类中继承,接下来就可以正常调用自己的实例方法了


二、继承:
下面的示例说明了子类继承父类

#!/usr/bin/env python
 
class Resource(object):                 #定义一个父类,继承于object基类
 
       def __new__(cls,*args,**kwargs):        #构造方法
                print &#39;class resource __new__&#39;
                obj =super(Resource,cls).__new__(cls,*args,**kwargs)            #利用super函数找到自己的父类,并将它的构造方法传递给obj
                print obj.__class__        #打印obj的类型
                return obj                     #返回值为obj
 
       def __init__(self):                       #初始化方法
                print "call me init forResource"
 
       def test(self):
                print "call me test forResource"
 
       def create(self):
                print "call me create forResource"
 
class subResource(Resource):               #定义子类,继承Resource父类
 
       def __init__(self):                #定义自己的初始化方法
                print &#39;sub resource init&#39;
 
       def test(self):
                print &#39;sub resource test&#39;
 
class Heat(object):                #定义一个Heat类,继承于基类object,是个新式类
 
       def __new__(cls,*args,**kwargs):               #定义自己的构造方法
                print "class __new__%s" % cls
                returnobject.__new__(cls,*args,**kwargs)                #返回值为object基类的构造方法的返回值
 
       def __init__(self):                #定义初始化方法
                print &#39;heat init&#39;
 
 
r = Heat()                     #实例化
print r
h = Resource()              #实例化
print h
f = subResource()          #实例化
print f
登录后复制

执行结果如下:

class __new__ <class &#39;__main__.Heat&#39;>               #实例化Heat类,首先执行自己的构造方法和初始化方法,所以先输出构造方法的print语句
heat init                        #执行了自己的初始化方法
<__main__.Heat object at0x7f43349ac050>                     #r实例化后继承的是object基类,打印返回值
class resource __new__                #实例化Resource类,首先执行自己的构造方法和初始化方法,所以先输出构造方法的print语句
<class &#39;__main__.Resource&#39;>         #打印父类构造方法的返回值的类名
call me init for Resource                     #执行自己的初始化方法
<__main__.Resource object at0x7f43349ac090>               # h实例化后继承的是object基类,打印返回值
 
class resource __new__                #实例化subResource类,首先执行父类的构造方法,所以先输出父类构造方法的print语句
<class &#39;__main__.subResource&#39;>           #父类构造方法里面打印自己的类名
sub resource init                   #执行自己的初始化方法
<__main__.subResource object at0x7f43349ac0d0>                 #f实例化后是执行了父类Resource类的构造方法,返回的依旧是object基类
登录后复制



三、多重继承:

#!/usr/bin/env python
 
class A(object):
       def __init__(self):
               pass
       def ma(self):
                print &#39;a.ma&#39;
       def m(self):
                print &#39;it is A&#39;
class B(object):
       def mb(self):
                print &#39;b.mb&#39;
       def m(self):
                print &#39;it is B&#39;
 
class C(A,B):
       pass
 
c = C()
c.ma()
c.mb()
c.m()
登录后复制

执行结果如下:

a.ma
b.mb
it is A
登录后复制

通过执行结果,我们可以看出,C是继承了A和B的,所以它可以调用A的ma()方法,也可以调用B的mb()方法;但是当A和B里面有相同的方法时,它会优先去执行继承的第一个超类。

四、继承和重载:

#!/usr/bin/env python
 
class Phone(object):
 
       def __init__(self,size,color,memory):
                self.size = size
                self.color = color
                self.memory = memory
 
       def call(self):
                s = &#39;I can call&#39;
                return s
       def sms(self):
                s = &#39;Are you gua le mei?&#39;
#!/usr/bin/env python
 
class Phone(object):
 
       def __init__(self,size,color,memory):
                self.size = size
                self.color = color
                self.memory = memory
 
       def call(self):
                s = &#39;I can call&#39;
                return s
       def sms(self):
                s = &#39;Are you gua le mei?&#39;
                return s
 
class Phones(Phone):            #继承了Phone类,重载了自己的初始化方法,又增加了自己的方法,既拥有超类的方法,又有自己特有的方法
 
       def __init__(self,size,color,memory,pix):
                self.pix = pix
               super(Phones,self).__init__(size,color,memory)
 
       def install_app(self,app):
                s = &#39;install %s&#39; % app
                return s
 
class Huwei(Phone):                    #继承了Phone类,又增加了自己的方法,既拥有超类的方法,又有自己特有的方法
 
       def weixin(self,msg):
                if msg.find(&#39;gcd&#39;) == -1:
                        return &#39;sending....&#39;
                else:
                        return &#39;You can\&#39;t sendthe msg&#39;
 
p = Phone(1.2,&#39;black&#39;,&#39;4M&#39;)                  #实例化
 
iphone =Phones(4.7,&#39;white&#39;,&#39;4G&#39;,&#39;1280*766&#39;)        #实例化
 
h = Huwei(4.7,&#39;yellow&#39;,&#39;4G&#39;)                #实例化
 
print iphone.install_app(&#39;weixin&#39;)          #执行特有的install_app方法
 
print h.sms()
print h.call()
print h.weixin(&#39;wansui&#39;)
sms = p.sms()
call = p.call()
print sms,call
登录后复制

执行结果如下:

install weixin
Are you gua le mei?
I can call
sending....
Are you gua le mei? I can call
登录后复制

方法的重载实际上就是在类中使用def关键字重载父类的方法。如果重载父类中的方法,但又需要
在类中使用父类的该方法,可以使用父类名加‘ .’加方法名的形式调用

五、魔术方法:

#!/usr/bin/env python
 
class Information(object):
       &#39;&#39;&#39;This is a doc                #说明文档
                example for test,please don&#39;tchange it.
       &#39;&#39;&#39;
 
       def __init__(self,sch,cla,m,n):             #定义初始化方法
                print "welecome to schoolsystem."
                self.school = sch                   #实例变量
                self.classroom = cla                     #实例变量
                self.num = 100                     #实例变量
                self.__money = m                #私有变量
                self.num = n                        #实例变量
 
       def school_name(self):                 #返回实例变量,即将实例变量传递出去
                return self.school
 
       def class_name(self):                   #返回实例变量,即将实例变量传递出去
                return self.classroom
 
       def class_money(self):                 #返回私有变量,即将私有变量传递出去
                return self.__money
              #魔术方法:以双下划线开头,以双下划线结尾的方法是魔术方法
       def __eq__(self,another):             #当外部出现&#39;==&#39;比较的时候,调用此魔术方法
                return self.__money ==another.__money           #返回两个私有变量的比较结果(布尔值),这里self是&#39;==&#39;左边的参数值,another是右边的参数值
 
       def __gt__(self,another):                     #当外部出现&#39;>&#39;比较的时候,调用此魔术方法
                return self.__money >another.__money             #返回两个私有变量的比较结果(布尔值),这里self是&#39;>&#39;左边的参数值,another是右边的参数值
 
       def __ne__(self,another):             #当外部出现&#39;!=&#39;比较的时候,调用此魔术方法
                return self.__money !=another.__money            #返回两个私有变量的比较结果(布尔值),这里self是&#39;!=&#39;左边的参数值,another是右边的参数值
 
       def __add__(self,another):            #当外部出现&#39;+&#39;运算符的时候,调用此魔术方法
                return self.__money +another.__money      #返回两个私有变量的相加结果,这里self是&#39;!=&#39;左边的参数值,another是右边的参数值
                #returnInformation(&#39;jiaoda&#39;,&#39;dz1302&#39;,self.__money + another.__money)
                #return Information(&#39;jiaoda&#39;,&#39;dz1302&#39;,1024,self.num+ another.num)
 
       def __str__(self):
                return &#39;money = %d&#39; %self.__money
 
       def __hash__(self):               #获取hash值
                return 1314521
 
       def __getattr__(self,name):                  #当调用不存在的方法时,执行此方法进行输出
                print "get attr %s" %name
                return name
 
       def __del__(self):          #析构方法,当不再使用此类时,会自动执行
                print "Goodbye,welecomhere again."
 
f = Information(&#39;youdian&#39;,&#39;tg1312&#39;,9999,6)           #实例化
l = Information(&#39;ligong&#39;,&#39;jk1213&#39;,6666,4)             #实例化
print f == l            #调用魔术方法__eq__()
print f + l                     #调用魔术方法__add__()
print f > l                     #调用魔术方法__gt__()
 
s = f + l                 #
print s
print f.ccc              #名字不存在,调用__getatter__()方法
登录后复制



__str__是被print函数调用的,一般都是return一个什么东西。这个东西应该是以字符串的形式表现的。如果不是要用str()函数转换。当你打印一个类的时候,那么print首先调用的就是类里面的定义的__str__

执行结果如下:

welecome to school system.          #首先会在实例化的时候执行初始化方法
welecome to school system.          #第二次实例化调用初始化方法
False                     #打印__eq__()的返回值为False
16665                   #打印__add__()的返回值为两数相加
True                      #打印__gt__()的返回值为True
16665
get attr ccc             #执行__getattr__()方法
ccc
Goodbye,welecom here again.             #执行完会自动执行析构函数
Goodbye,welecom here again.
登录后复制



六、模块:
在python中,自带200多个模块,现在经过大家的不断完善以及改进,官网已经收集了两千多库模块,几乎可以实现任何你想要的功能。

在我们自己使用时,也可以使用自己的模块,任何一个.py都可以作为一个单独的模块进行导入;

现在我们首先定义一个自己的模块:module.py

#!/usr/bin/env python
#coding=utf-8
 
def test():
       print&#39;This is a test&#39;
 
def test2():
       print&#39;test2&#39;
 
class DB(object):
       def__init__(self):
              self.a= 101
       deftest(self):
              returnself.a
登录后复制

在同一目录下,打开python交互式就可以导入这个模块,名字就是文件的名module;
在文件中写入进行导入调用,,,,,这里是在同一目录下(同一层)

#!/usr/bin/env python
 
import module
module.test()
登录后复制

结果如下:

This is a test
登录后复制

改进一下,进行调用模块中的类:

#!/usr/bin/env python
 
import module
h = module.DB()
print h.test()
登录后复制

输出结果如下:

101
登录后复制

下面我们试着去导入一个目录下的模块:
新建一个目录heat,在里面写入几个模块文件
目录下必须有__init__.py才能被当做模块导入

python学习之面向对象编程特性(二)


在heat目录下的docker.py内容为:

#!/usr/bin/env python
 
def docker():
       return&#39;This is a docker in heat&#39;
 
class Docker(object):
       defcreate_c(self):
              return&#39;1314521aaa&#39;
 
       defstop_c(self):
              return&#39;it is stop&#39;
 
print __name__
 
if __name__ == &#39;__main__&#39;:
       print__name__
       d= Docker()
登录后复制



在heat目录下的nova.py内容为:

#!/usr/bin/env python
 
def nova():
       return&#39;This is a nova&#39;
 
class Nova(object):
       deftest(self):
              return&#39;This is a test in nova&#39;
登录后复制



现在heat目录下只是有__init__这个文件,文件里面无内容

写一个调用的脚本文件:

#!/usr/bin/env python
#coding=utf-8
 
import heat.docker               #目录下__init__.py里面没有__all__
printheat.docker.docker()
登录后复制

执行结果如下:

heat.docker
This is a docker in heat
This is a docker in heat
登录后复制

现在只能导入目录下的具体的模块,像上面一样导入和调用;

为了将目录下的所有模块文件都可以被导入,可以在目录下的__init__.py里面加下以下内容:

__all__ = [&#39;docker&#39;,&#39;nova&#39;]                    #将所有模块名字写入
登录后复制

改变执行文件内容:

#!/usr/bin/env python
#coding=utf-8
 
import heat.docker               #目录下__init__.py里面没有__all__
print heat.docker.docker()
 
from heat import *               #heat目录下__init__里面内容是:__all__ = [&#39;docker&#39;,nova&#39;]
print docker.docker()
print nova.nova()
n = nova.Nova()
print n.test()
登录后复制

执行结果如下:

heat.docker
This is a docker in heat
This is a docker in heat
This is a nova
This is a test in nova
登录后复制

如果在目录下还有目录里面存在需要导入的模块,可以继续在里面写__init__.py文件,并把目录下模块文件的名字写进去,在调用时多加一层目录就可以了。

python学习之面向对象编程特性(二)

下面示例一下里面mod.py文件内容:

#!/usr/bin/env python
#coding=utf-8
 
def hello():
       return&#39;hello everyone&#39;
 
class Hello(object):
       def__init__(self):
              self.a= 103
       deftest(self):
              return&#39;This is a test in Hello&#39;
登录后复制

执行下面的脚本进行测试:

#!/usr/bin/env python
#coding=utf-8
 
from heat.common import mod
 
print mod.hello()
h = mod.Hello()
print h.test()
登录后复制

执行结果如下:

hello everyone
This is a test in Hello
登录后复制



如果需要里面的所有模块文件,还是继续在__init__.py文件里写入就好了。

需要注意的是,文件被当做模块导入时,会产生.pyc文件,如果更改了模块,应该刷新.pyc文件,否则读取的还是旧信息。

为了防止文件是被作为模块使用的,我们应该在文件中加入

if __name__ == &#39;__main__&#39;:
       pass               #这里是要执行的语句
登录后复制


这样就可以防止当文件是被用作模块使用时,不会被执行if下面的语句,如果是当做程序来执行时,则会执行下面的语句,一般用作测试。

本文出自 “ptallrights” 博客,请务必保留此出处http://ptallrights.blog.51cto.com/11151122/1793746

以上是python学习之面向对象编程特性(二) 的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1653
14
CakePHP 教程
1413
52
Laravel 教程
1304
25
PHP教程
1251
29
C# 教程
1224
24
PHP和Python:解释了不同的范例 PHP和Python:解释了不同的范例 Apr 18, 2025 am 12:26 AM

PHP主要是过程式编程,但也支持面向对象编程(OOP);Python支持多种范式,包括OOP、函数式和过程式编程。PHP适合web开发,Python适用于多种应用,如数据分析和机器学习。

在PHP和Python之间进行选择:指南 在PHP和Python之间进行选择:指南 Apr 18, 2025 am 12:24 AM

PHP适合网页开发和快速原型开发,Python适用于数据科学和机器学习。1.PHP用于动态网页开发,语法简单,适合快速开发。2.Python语法简洁,适用于多领域,库生态系统强大。

PHP和Python:深入了解他们的历史 PHP和Python:深入了解他们的历史 Apr 18, 2025 am 12:25 AM

PHP起源于1994年,由RasmusLerdorf开发,最初用于跟踪网站访问者,逐渐演变为服务器端脚本语言,广泛应用于网页开发。Python由GuidovanRossum于1980年代末开发,1991年首次发布,强调代码可读性和简洁性,适用于科学计算、数据分析等领域。

Python vs. JavaScript:学习曲线和易用性 Python vs. JavaScript:学习曲线和易用性 Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

sublime怎么运行代码python sublime怎么运行代码python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中运行 Python 代码,需先安装 Python 插件,再创建 .py 文件并编写代码,最后按 Ctrl B 运行代码,输出会在控制台中显示。

vs code 可以在 Windows 8 中运行吗 vs code 可以在 Windows 8 中运行吗 Apr 15, 2025 pm 07:24 PM

VS Code可以在Windows 8上运行,但体验可能不佳。首先确保系统已更新到最新补丁,然后下载与系统架构匹配的VS Code安装包,按照提示安装。安装后,注意某些扩展程序可能与Windows 8不兼容,需要寻找替代扩展或在虚拟机中使用更新的Windows系统。安装必要的扩展,检查是否正常工作。尽管VS Code在Windows 8上可行,但建议升级到更新的Windows系统以获得更好的开发体验和安全保障。

vscode在哪写代码 vscode在哪写代码 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中编写代码简单易行,只需安装 VSCode、创建项目、选择语言、创建文件、编写代码、保存并运行即可。VSCode 的优点包括跨平台、免费开源、强大功能、扩展丰富,以及轻量快速。

notepad 怎么运行python notepad 怎么运行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中运行 Python 代码需要安装 Python 可执行文件和 NppExec 插件。安装 Python 并为其添加 PATH 后,在 NppExec 插件中配置命令为“python”、参数为“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通过快捷键“F6”运行 Python 代码。

See all articles