北京治疗白癜风总共要花多少钱 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.__ageage.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 |