Python-类和对象
对象=属性(变量)+方法(函数)
面向对象的特征(OO=Object Oriented)
1.封装:
对象封装了属性和方法,成为一个独立性很强的模块。封装也是一种信息隐蔽技术
2.继承:
是子类自动共享父类之间的数据和方法的机制
语法: class DerivedClassName(BaseClassName): class 子类名称(父类/基类/超类名称)
....
# 继承 class Parent: def hello(self): print('正在调用父类的方法。。。。') class Child(Parent): pass p = Parent() p.hello() c = Child() c.hello() 执行结果: 正在调用父类的方法。。。。 正在调用父类的方法。。。。
注意:如果子类定义与父类同名的方法或属性,则会自动覆盖父类对应的方法或属性
# 继承 class Parent: def hello(self): print('正在调用父类的方法。。。。') class Child(Parent): def hello(self): print('正在调用子类的方法。。。。') p = Parent() p.hello() c = Child() c.hello() 执行结果: 正在调用父类的方法。。。。 正在调用子类的方法。。。。
子类重写父类方法后,仍想使用原父类中的方法。
1.调用未绑定的父类方法
2.使用super函数
import random as r class Fish: def __init__(self): self.x = r.randint(0,10) self.y = r.randint(0,10) def move(self): self.x -=1 print('我的位置是:', self.x, self.y) class Goldfish(Fish): pass class Carp(Fish): pass class Salmon(Fish): pass class Shark(Fish): def __init__(self): # 调用未绑定的父类方法 Fish.__init__(self) super().__init__() #super()函数直接使用函数名即可继承父类对应函数 self.hungry = True def eat(self): if self.hungry: print('吃货的梦想就是天天有的吃!!!') self.hungry = False else: print('太撑了,吃不下了~~') shark = Shark() shark.move() shark.eat() shark.eat() 执行结果: 我的位置是: 8 3 吃货的梦想就是天天有的吃!!! 太撑了,吃不下了~~
多重继承
语法: class DerivedClassName(Base1, Base2, Base3):
...
# 多重继承 class Base1: def foo1(self): print('我是foo1,我为Base1代言。。。') class Base2: def foo2(self): print('我是foo2,我为Base2代言。。。') class C(Base1,Base2): pass d = C() d.foo1() d.foo2() 执行结果: 我是foo1,我为Base1代言。。。 我是foo2,我为Base2代言。。。
3.多态:
不同对象对同一方法响应不同的行动
# 不同对象调用同一方法 class Ball: def setName(self,name): self.name = name def kick(self): print('我叫%s,该死的,谁踢我。。。'% self.name) a = Ball() a.setName('小脑斧') b = Ball() b.setName('小西几') a.kick() b.kick()
构造方法:只要实例化一个对象,这个方法就会在创建对象的时候自动调用
实例化对象的时候是可以传入参数的,参数会自动存在_init_方法中
# 构造方法 class Animal: def __init__(self,name): self.name = name def adress(self): print('我是%s,我住在大山里~'% self.name) c = Animal('小熊猫') c.adress()
私有变量
name mangling:名字改编,名字重整
在Python中定义私有变量只需要在变量名或函数名前加上“_”两个下划线,那么这个函数或变量就会变为私有的了。
在函数外无法调用私有变量:
可以从函数内部调用私有变量:
Python中的私有是伪私有,他是自动把带有双下划线的变量名称进行修改,修改为“_类名__变量名”
组合:实现横向关系的类(即没有继承关系的类)放在一起
# 现在要求定义一个类,叫水池,水池里要有乌龟和鱼 class Wugui: def __init__(self, x): self.num = x class Fish: def __init__(self,x): self.num = x class Pool: def __init__(self, x, y): self.wugui = Wugui(x) #把需要的类实例化放入即可 self.fish = Fish(y) def print_num(self): print('水池里有%d只乌龟,%d只鱼~~~' % (self.wugui.num, self.fish.num)) pool = Pool(5, 45) pool.print_num() 执行结果: 水池里有5只乌龟,45只鱼~~~
类、类对象、实例对象
注意:若属性名和方法名相同,则属性名会覆盖方法名
所以:不要试图在一个类里面定义出所有能想的到的特性和方法,应该用继承和组合机制来进行扩展。
用不同的词性命名,如属性名用名词,方法名用动词。
绑定:
Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念
类和对象相关内置函数
1.issubclass(class,classinfo):判断第一个参数是不是第二个参数的子类,如果是,返回True
1.非严格性检查,即一个类被认为是其自身的子类
2.classinfo可以是类对象组成的元组,只要class与其中任何一个候选类的子类,则返回True
object是所有类的基类
2.isinstance(object,classinfo):检查一个实例对象是否属于一个类
1.如果第一个参数不是对象类型,则永远返回False
2.如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError异常
3.hasattr(object,name):对象里面是否有指定的属性,name需要有引号括起来,表示字符串
attr = attribute:属性
4.getattr(object,name[,default]):返回对象指定属性值,如果指定属性不存在,若设置default参数,则打印default的值,否则抛出AttributeError的异常
5.setattr(object,name,value):设置对象中指定属性的值,如果指定属性不存在,就会新建该属性,并给他赋值
6. delattr(object,name):删除对象中指定属性的值,如果指定属性不存在,则抛出AttributeError的异常
7.property(fget = None ,fset = None, fdel = None, doc = None):通过属性来设置属性
第1个参数:获得属性
第2个参数:设置属性
第3个参数:删除属性