面向对象(object-oriented ;简称: OO) :按人们 认识客观世界的系统思维方式,采用基于对象(实体) 的概念建立模型,模拟客观世界分析、设 计、实现软件的办法。
python是动态语言。动态编程语言是高级程序设计语言的一个类别,可以在运行时改变其结构的语言。
面向对象编程(Object Oriented Programming-OOP) 是一种解决软件复用的设计和编程方法。 这种方法把软件系统中相近相似的操作逻辑和操作应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。Car(object)则为新式类类名命名规则"大驼峰"首字母大写。
__test()=>私有方法(2个下划线)
__name =>私有属性
__new__():实例化对象时调用
__init__():初始化属性
__del__():代码执行完删除对象
__all__:在__init__()中使用,决定from A import*的内容。
如果一个文件中有__all__变量,那么也就意味着这个变量中的元素,不会被from xxx import *时导入
if __name__ ='__main__':
main()
可以根据__name__变量的结果能够判断出,是直接执行的python脚本还是被引入执行的,从而能够有选择性的执行测试代码
为了达到限制的目的,python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例来添加的属性。
class Person(object):
__slots__=("name","age")
当使用del删除变量指向的对象时,如果对象的引用计数不会1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次__del__(),此时会真的把对象进行删除
魔法方法:
__str__():retrun类的说明,print(类)时输出
__iter__():一个具备了__iter__
方法的对象,就是一个可迭代对象。
__next__():在使用next()函数的时候,调用的就是迭代器对象的__next__
方法
如果有一个对象,当需要对其进行修改属性时,有2种方法:
对象名.属性名 = 数据 ---->直接修改
对象名.方法名() ---->间接修改
私有的方法,不能通过对象直接访问
私有的属性、方法,不会被子类继承,也不能被访问
一般情况下,私有的属性、方法都是不对外公布的,往往用来做内部的事情,起到安全的作用
python中是可以多继承的
父类中的方法、属性,子类会继承
如果在上面的多继承例子中,如果父类A和父类B中,有一个同名的方法,那么通过子类去调用的时候,调用class C(A,B):一般调A的,初始化方法__init__()只会执行A里面的,因此C 的属性时继承的A里面的。
在多继承中,class B(A,C):如果A中有init方法,B的初始化就会走A这边,从而获取A的属性,因此C的属性就不能获取到。(实际中遇到的问题,请教了老师)
__init__方法往往是用来对创建完的对象进行初始化工作,如果在子类中重写了父类的__init__方法,即意味着父类中的很多初始化工作没有做,这样就不保证程序的稳定了,所以在以后的开发中,如果重写了父类的__init__方法,最好是先调用父类的这个方法,然后再添加自己的功能
所谓重写,就是子类中,有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法
所谓多态:定义时的类型和运行时的类型不一样,此时就成为多态
多态的概念是应用于Java和C#这一类强类型语言中,而Python崇尚“鸭子类型”。
鸭子类型(duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问不能在类外通过实例对象访问私有的类属性
在类里面定义的都是类属性包括私有属性和公有属性,在类的方法里面定义的是实例属性。
如果需要在类外修改类属性,必须通过类对象去引用然后进行修改。
如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且之后如果通过实例对象去引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性。
类方法:是类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以'cls'作为第一个参数的名字,就最好用'cls'了),能够通过实例对象和类对象去访问。
class People(object):
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country
p = People()
print p.getCountry() #可以用过实例对象引用
print People.getCountry() #可以通过类对象引用
也可以通过类方法对类属性进行修改:
class People(object):
country = 'china'
#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country
@classmethod
def setCountry(cls,country):
cls.country = country
p = People()
print p.getCountry() #可以用过实例对象引用
print People.getCountry() #可以通过类对象引用
p.setCountry('japan')
print p.getCountry()
print People.getCountry()
静态方法:
需要通过修饰器@static来进行修饰,静态方法不需要定义参数从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在 存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用
property的用法:
num = property(getNum, setNum)
注意:t.num到底是调用了getNum()还是setNum(),要根据实际的场景来判断
1.如果是赋值,调用setNum
2.如果是获取值,调用getNum
Property的作用:相当于把方法进行了封装,开发者在对属性设置数据的时候更方便。
class A:
def __init__(self):
self.__num2 = 200
def __test(self):
print('是由方法%d%d')
class B(A):
pass
b._A__test()
print(b._A__num2)
通过"’_父类名称__私有方法"来调用父类的私有属性和私有方法。
每一个对象都有自己独立的内存空间,保存各自不同的属性
多个对象的方法,在内存中只有一份,在调用方法是,需要把对象的引用传递到方法内部。
在模块中,只要python执行的时候执行,别人调不让调:
if __name =="__main__"
XXXX
dir():查看内容。
TODO(小明):提醒程序员小明还没有完善的功能以及应该由谁写完的代码。
希望修改全局变量的值--使用global声明一下变量即可
global关键字会告诉解释器后面的变量是一个全局变量
在使用赋值语句的时候,就不会创建局部变量。
为了保证所有的函数都能正确的使用到全局变量,应该将全局变量定义在其他函数的上方。
为了避免局部变量和全局变量出现混淆,在定义变量时,可以再全局变量前增加g_ 或者gl_的前缀。