时间:2021-9-1来源:本站原创作者:佚名
北京治疗白癜风总共要花多少钱 http://m.39.net/pf/a_4591483.html

Tips:Python免费课程报名中,点击文末“阅读原文”快速抢!

面向对象编程和函数式编程(面向过程编程)都是程序设计的方法,不过稍有区别。

面向过程编程:

1.导入各种外部库2.设计各种全局变量3.写一个函数完成某个功能4.写一个函数完成某个功能5.写一个函数完成某个功能6.写一个函数完成某个功能7.写一个函数完成某个功能8.......9.写一个main函数作为程序入口

在多函数程序中,许多重要的数据被放置在全局数据区,这样它们可以被所有的函数访问。每个函数都可以具有它们自己的局部数据,将某些功能代码封装到函数中,日后便无需重复编写,仅调用函数即可。从代码的组织形式来看就是根据业务逻辑从上到下垒代码。

面向对象编程:

1.导入各种外部库2.设计各种全局变量3.决定你要的类4.给每个类提供完整的一组操作5.明确地使用继承来表现不同类之间的共同点6.根据需要,决定是否写一个main函数作为程序入口

面向对象编程中,将函数和变量进一步封装成类,类才是程序的基本元素,它将数据和操作紧密地连结在一起,并保护数据不会被外界的函数意外地改变。类和和类的实例(也称对象)是面向对象的核心概念,是和面向过程编程、函数式编程的根本区别。

并不是非要用面向对象编程,要看你的程序怎么设计方便,但是就目前来说,基本上都是在使用面向对象编程。

类的基本用法

面向对象是通过定义class类来定义,这么说面向对象编程就是只使用class类,在class类中有封装,继承的功能,并且还可以构造要传入的参数,方便控制。

案例一

importsysimporttimereload(sys)sys.setdefaultencoding(utf-8)classstudetn:#定义一个类名为studetndef__init__(self,idx):#定义初始化构造,这里使用init,还有别的属性比如reversed,iter之类的self.idx=idx#初始化变量,方便继承defrunx(self):#定义运行函数,从上面继承变量printself.idx#打印出idx的值,或者做一些别的处理time.sleep(1)a=studetn(a)a.runx()#这是类的调用,一定要记得类的使用方法,首先传入参数,类赋值给一个变量a#然后调用这个类下面定义的函数

一些专业术语概念,既然有面向对象编程这个高大上的定义了,自然要搭配一些高大上的概念。

类(Class):用来描述具有相同属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。其中的对象被称作类的实例。

实例:也称对象。通过类定义的初始化方法,赋予具体的值,成为一个”有血有肉的实体”。

实例化:创建类的实例的过程或操作。

实例变量:定义在实例中的变量,只作用于当前实例。

类变量:类变量是所有实例公有的变量。类变量定义在类中,但在方法体之外。

数据成员:类变量、实例变量、方法、类方法、静态方法和属性等的统称。

方法:类中定义的函数。

静态方法:不需要实例化就可以由类执行的方法

类方法:类方法是将类本身作为对象进行操作的方法。

方法重写:如果从父类继承的方法不能满足子类的需求,可以对父类的方法进行改写,这个过程也称override。

封装:将内部实现包裹起来,对外透明,提供api接口进行调用的机制

继承:即一个派生类(derivedclass)继承父类(baseclass)的变量和方法。

多态:根据对象类型的不同以不同的方式进行处理。

类与实例

#-*-coding:utf-8-*-#

Time:/5/:02#

Author:Langzi#

Blog:   执行__getitem__方法标识符[]=a:   执行__setitem__方法del标识符[] :   执行__delitem__方法

如果有一个类同时定义了这三个魔法方法,那么这个类的实例的行为看起来就像一个字典一样,如下例所示:

classFoo: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__delobj[k1]#自动触发执行__delitem__9.iter()

这是迭代器方法!列表、字典、元组之所以可以进行for循环,是因为其内部定义了iter()这个方法。如果用户想让自定义的类的对象可以被迭代,那么就需要在类中定义这个方法,并且让该方法的返回值是一个可迭代的对象。当在代码中利用for循环遍历对象时,就会调用类的这个iter()方法。

普通的类:

classFoo:passobj=Foo()foriinobj:print(i)#报错:TypeError:Fooobjectisnotiterablebr#原因是Foo对象不可迭代添加一个__iter__(),但什么都不返回:classFoo:def__iter__(self):passobj=Foo()foriinobj:print(i)#报错:TypeError:iter()returnednon-iteratoroftypeNoneType#原因是__iter__方法没有返回一个可迭代的对象

返回一个个迭代对象:

classFoo:def__init__(self,sq):self.sq=sqdef__iter__(self):returniter(self.sq)obj=Foo([11,22,33,44])foriinobj:print(i)

最好的方法是使用生成器:

classFoo:def__init__(self):passdef__iter__(self):yield1yield2yield3obj=Foo()foriinobj:print(i)10、len()

在Python中,如果你调用内置的len()函数试图获取一个对象的长度,在后台,其实是去调用该对象的len()方法,所以,下面的代码是等价的:

len(ABC)3ABC.__len__()3

Python的list、dict、str等内置数据类型都实现了该方法,但是你自定义的类要实现len方法需要好好设计。

11.repr()

这个方法的作用和str()很像,两者的区别是str()返回用户看到的字符串,而repr()返回程序开发者看到的字符串,也就是说,repr()是为调试服务的。通常两者代码一样。

classFoo:def__init__(self,name):self.name=namedef__str__(self):return"thisis%s"%self.name__repr__=__str__12.add__:加运算_sub_:减运算_mul_:乘运算_div_:除运算_mod_:求余运算__pow:幂运算

这些都是算术运算方法,需要你自己为类设计具体运算代码。有些Python内置数据类型,比如int就带有这些方法。Python支持运算符的重载,也就是重写。

classVector:def__init__(self,a,b):self.a=aself.b=bdef__str__(self):returnVector(%d,%d)%(self.a,self.b)def__add__(self,other):returnVector(self.a+other.a,self.b+other.b)v1=Vector(2,10)v2=Vector(5,-2)print(v1+v2)13.author作者信息

__author__="Jack"defshow():print(__author__)show()14.slots

Python作为一种动态语言,可以在类定义完成和实例化后,给类或者对象继续添加随意个数或者任意类型的变量或方法,这是动态语言的特性。例如:

defprint_doc(self):print("haha")classFoo:passobj1=Foo()obj2=Foo()#动态添加实例变量obj1.name="jack"obj2.age=18#动态的给类添加实例方法Foo.show=print_docobj1.show()obj2.show()

但是!如果我想限制实例可以添加的变量怎么办?可以使slots限制实例的变量,比如,只允许Foo的实例添加name和age属性。

defprint_doc(self):print("haha")classFoo:__slots__=("name","age")passobj1=Foo()obj2=Foo()#动态添加实例变量obj1.name="jack"obj2.age=18obj1.sex="male"#这一句会弹出错误#但是无法限制给类添加方法Foo.show=print_docobj1.show()obj2.show()由于sex不在__slots__的列表中,所以不能绑定sex属性,试图绑定sex将得到AttributeError的错误。Traceback(mostrecentcalllast):File"F:/Python/pycharm//1.py",line14,inmoduleobj1.sex="male"AttributeError:Fooobjecthasnoattributesex

需要提醒的是,slots定义的属性仅对当前类的实例起作用,对继承了它的子类是不起作用的。想想也是这个道理,如果你继承一个父类,却莫名其妙发现有些变量无法定义,那不是大问题么?如果非要子类也被限制,除非在子类中也定义slots,这样,子类实例允许定义的属性就是自身的slots加上父类的slots。

成员保护与访问机制

有些对象你不想外部访问,即使是通过调用类对象也无法访问,那就请认真学完本章节。

私有成员

classobj:def__init__(self,name):self.name=namedefpri(self):printself.name__age=18#加上双下划线的就是私有变量,只能在类的内部访问,外部无法访问a=obj(zhao)a.pri()

运行结果:

zhao

如果要在类中调用这个私有成员,可以这么用

classobj:def__init__(self,name):self.name=namedefprin(self):printself.name__age=18#加上双下划线的就是私有变量,只能在类的内部访问,外部无法访问

classmethod#如果要在类中调用,首先调用类方法defpri(cls):printcls.__age#然后在使用a=obj(zhao)a.prin()obj.pri()#通过这样直接调用类中的私有变量

运行结果:

zhao18使用get-set-del方法操作私有成员

classobj:def__init__(self,name):self.name=namedefprin(self):printself.name__age=18#加上双下划线的就是私有变量,只能在类的内部访问,外部无法访问

classmethod#如果要在类中调用,首先调用类方法defpri(cls):printcls.__age#然后在使用

classmethoddefset_age(cls,value):cls.__age=valuereturncls.__age#这个用法就是改变__age的值

classmethoddefget_age(cls):returncls.__age#这个用法就是直接返回__age的值

classmethoddefdel_age(cls):delcls.__age#这个用法就是直接删除__age的值printobj.get_age()#这里是直接调用出__age的值返回值18printobj.set_age(20)#这里是直接改变__age的值返回值20obj.del_age()#这里是直接删除__age的值

思考:既然是私有变量,不让外部访问,为何有要在后面调用又改变呢?因为可以对私有变量进行额外的检测,处理,加工等等。比如判断value的值,使用isinstance然后做if-else判断。

使用私有变量可以对内部变量进行保护,外部无法改变,但是可以对它进行检测处理。

这里引申一下私有成员的保护机制,使用__age对私有变量其实就是—obj._obj__age的样子进行保护,说白了你直接使用obj._obj__age就可以直接调用内部私有变量age了。

Propety装饰器

把类的方法伪装成属性调用的方式,就是把类里面的一个函数,变成一个属性一样的东西~一开始调用类的方法要使用圆括号,现在变成了属性进行读取设置存储。举个例子来说明:

常用的调用方法

classobj:def__init__(self,name,age):self.__name=nameself.__age=age#讲这些设置成私有变量defget_age(self):returnself.__agedefset_age(self,value):ifisinstance(value,int):self.__age=valueelse:raiseValueError(非整数类型)defdel_age(self):printdeleteovera=obj(langzi,18)printa.get_age()a.set_age(20)printa.get_age()使用装饰器

classobj:def__init__(self,name,age):self.__name=nameself.__age=age#把这些设置成私有变量

propertydefage(self):returnself.__age

age.setterdefage(self,value):ifisinstance(value,int):self.__age=valueelse:raiseValueError(非整数类型)

age.deleterdefage(self):printdeleteovera=obj(langzi,18)#使用这些装饰器,可以使用类与对象的方法直接调用printa.age#这里就是直接调用返回age的值a.age=20#这里就是直接使用setter把值转换printa.agedela.age#删除age

当然这种调用方法有些麻烦,每次都是一个一个去实例类与对象,有个更加简单直观的方法。

更加减半的使用property()函数

除了使用装饰器的方式将一个方法伪装成属性外,Python内置的builtins模块中的property()函数,为我们提供了第二种设置类属性的手段。

classPeople:def__init__(self,name,age):self.__name=nameself.__age=agedefget_age(self):returnself.__agedefset_age(self,age):ifisinstance(age,int):self.__age=ageelse:raiseValueErrordefdel_age(self):print("删除年龄数据!")#核心在这句age=property(get_age,set_age,del_age,"年龄")obj=People("jack",18)print(obj.age)obj.age=19print("obj.age:",obj.age)delobj.ag

通过语句age=property(get_age,set_age,del_age,“年龄”)将一个方法伪装成为属性。其效果和装饰器的方法是一样的。

property()函数的参数:

第一个参数是方法名,调用实例.属性时自动执行的方法第二个参数是方法名,调用实例.属性=XXX时自动执行的方法第三个参数是方法名,调用del实例.属性时自动执行的方法第四个参数是字符串,调用实例.属性.__doc__时的描述信息。

转自:浪子燕青

Python人工智能0基础免费训练营,名师主讲基础知识,快速提升技术,深入探索人工智能未来前景!长按
转载请注明原文网址:http://www.helimiaopu.com/cxkf/cxkf/10965.html
------分隔线----------------------------