python 学习笔记7
类和对象
对象:属性+方法;类相当于是对象的图纸,使对象达到量产的效果 类定义出来后,其和类对象互相绑定,并不会因为实例对象的改变而改变 当实例对象的属性/方法改变时,会创造一个新的同名属性/方法覆盖原来的属性/方法。为了避免重名,尽量不要在一个类中定义出所有能想到的属性/方法,也就是尽量拆分,然后通过组合或继承组合起来。
类的创建
class Turtle:
color = 'green'
weight = 10
legs = 4
shell = True
mouth = '大嘴'
def climb(self):
print('climbing...')
def run(self):
print('running...')
def eat(self):
print('eating')
def sleep(self):
print('sleeping')
创建实例化对/类的实例化
tt = Turtle()
tt.climb()
tt.run()
OO(Object Oriented)/面向对象的特征
OOP(Object Oriented Program):面向对象编程 OOA(Object Oriented Analysis):面向对象分析 OOD(Object Oriented Design):面向对象设计
1、封装
将一些方法打包进入一个类,不需要知道方法的机制,只需要知道方法的使用方式和效果就可以使用
2、继承
class DerivedClassName(BaseClassName):
class DerivedClassName(BaseClassName1,BaseClassName2,...):
其中DerivedClassName为子类,BaseClassName为基类/父类/超类 子类可以继承父类的属性、方法。 多重继承时要谨慎,可能会出现不可预见的bug
class Parent:
def hello(self):
print("正在调用父类方法")
class Child(Parent):
pass
p = Parent()
p.hello()
c = Child()
c.hello()
如果子类定义与父类同名的方法或属性,会覆盖父类的方法或属性
class Child1(Parent):
def hello(self):
print("正在调用子类方法")
c1 = Child2()
c1.hello()
同样,子类的初始化会将父类的初始化覆盖,为了解决这个问题,有两种方法: ①调用未绑定的父类方法 将父类的初始化写入子类中,就不会被子类覆盖(不用一行一行复制,这样太蠢了,虽然也可以)
import random
class Fish():
def __init__(self):
self.x = random.randint(0,10)
self.y = random.randint(0,10)
def move(self):
self.x -= 1
print("现在的位置是:",self.x,self.y)
class Shark(Fish):
def __init__(self):
Fish.__init__(self)
self.hungry = True
def eat(self):
if self.hungry == True:
print('吃!!')
self.hungry = False
else:
print("嗝..饱了")
或者将子类的实例化对象丢到父类的初始化中去也可以实现
Fish.__init__(shark)
shark.move()
“绑定“请见后文 ②使用super函数 python提供的一个更好的方法,super函数会自动搜寻父类并继承所有父类的方法,更全面,当父类有很多时会更方便
将Fish.__init__(self) 替换为super().__init__()
3、多态
不同对象对于同一方法的不同相应
class A:
def fun(self):
print('我的小A')
class B:
def fun(self):
print('我的小B')
a = A()
b = B()
a.fun()
b.fun()
4、What is self?
Python的self相当于C++的this指针 由同一个类可以生成无数个对象,对象会将self作为第一个参数传入,因此虽然不同对象有相同的方法,但是不同的对象会有不同的实现,就是self在起作用,即将对象自身作为参数传入。
class Ball():
def setname(self,name):
self.name = name
def kick(self):
print('我是%s' % self.name)
a = Ball()
b = Ball()
c = Ball()
a.setname('sa')
b.setname('sb')
c.setname('ca')
a.kick()
b.kick()
c.kick()
5、__init__(self,param1,param2)
对象本身即可作为一个方法,定义__init__(self,param1,param2):——>可调用Ball(param1,param2):,在某些程度上更加方便
class Ball:
def __init__(self,name):
self.name = name
def kick(self):
print('我是%s' % self.name)
a = Ball('sa')
a.kick()
6、私有和公有
同一个类定义出来的对象中的方法是公有的,但也要有私有的,即同一个类定义出的对象的方法不同,在Python中定义私有变量只需要在变量名或函数名前加上"__"两个下划线,那么这个函数/变量就会变为私有的。
class Person:
__name = 'John'
def getName(self):
return self.__name
p.name
p.__name
p.getName()
7、组合
建一个水池,其中要有乌龟和鱼,用水池继承乌龟和鱼就会很奇怪。所谓组合就是把两个类的实例化放在一个新类中去。
class Turtle:
def __init__(self,x):
self.num = x
class Fish:
def __init__(self,x):
self.num = x
class Pool:
def __init__(self,x,y):
self.turtle = Turtle(x)
self.fish = Fish(y)
def print_num(self):
print("there are %d turtles and %d fish in the pool" %(self.turtle.num,self.fish.num))
调用:
pool = Pool(1,10)
pool.print_num()
8、绑定
Python严格要求方法需要有实例才能被调用,这就是绑定
9、相关BIF
① issubclass(class,classinfo):如果class是classinfo的子类就返回True,否则抛出TypeError。注意:一个类可以被认为是自身的子类;class,classinfo可以是元组 ②isinstance(object,classinfo):检查实例对象object是不是属于类classinfo,是则返回True,否则返回False,如果第一个参数不是实例对象,则返回False,如果后一个参数不是类,则报出TypeError。 ③hasattr(object,‘name’):检查object中是否有name属性,有则返回True ④getattr(object,‘name’[,default]):返回object中name属性值,如果指定的属性不存在,如果有设置default则返回default,否则报出AttributeError。 ⑤setsttr(object,‘name’,value):与getattr类似,如果指定属性不存在则创建这个属性并附上value的值 ⑥delattr(object,‘name’):删除实例对象的指定属性,如果属性不存在则抛出AttributeError的异常。 ⑦property(fget =None,fset = None, fdel = None,doc = None):设置属性,其中fget,fset,fdel分别为类中获得属性的方法、设置属性的方法和删除属性的方法。
class C:
def __init__(self,size = 10):
self.size = size
def getsize(self):
return self.size
def setsize(self,value):
self.size = value
def delsize(self):
del self.size
x = property(getsize, setsize, delsize)
c1 = C()
c1.x
c1.x = 18
del c1.x
|