知识点:类
- 类,类对象,实例对象
类定义完的时候,类定义就变成了类对象。注意:如果对象的方法名和属性同名,属性会覆盖方法。
class C: #类 count=0 #类对象 a = C() #类实例 b = C() #类实例 print(C.count) #类对象 print(a.count) #实例对象 print(b.count) #实例对象 print("------------------------------") C.count += 10 #类对象+10 print(C.count) #类对象 print(a.count) #实例对象 print(b.count) #实例对象 print("------------------------------") a.count+=10 print(C.count) #类对象 print(a.count) #实例对象 print(b.count) #实例对象
输出:
0
0
0
------------------------------
10
10
10
------------------------------
10
20
10
结论:实例对象如果没有单独操作过,那么实例对象的值会随着类对象的值变化。如果实例对象单独设置过,会覆盖类对象,不再随着类对象变化。
- 类的构造器 __init__
类的构造器为__init__(双下划线), 里面传递成员变量.使用self参数, 并把参数(argument)传递至self.val(泛指)的成员变量中.
成员函数, 可以使用self.val, 进行操作.
构造器__init__不能返回None以外的任何对象
1 class Person: 2 def __init__(self, name): #self是每个方法的默认参数,不需要设定,所有输入参数都是从第二个开始设置 3 self.name = name 4 def sayHi(self): 5 print('Hello, my name is ' + self.name) 6 7 8 p = Person('marian') #第一个参数self是默认参数,'marian'的设定是对name的赋值 9 p.sayHi() >>> Hello, my name is marian
- 类的继承
class DerivedClassName(baseClassName): #baseClassName:基类,父类或超类
....
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 Shark(Fish): #继承父类 def __init__(self): #重写父类方法 print("我要吃了你!") fish = Fish() fish.move()
>>> 我是位置是 5 9
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 Shark(Fish): def __init__(self):
super().__init__() #如果要修改父类的方法,可以先继承父类中方法的内容。加入此句,可以解决下面的错误 print("我要吃了你!") shark = Shark() shark.move() ################################### #Traceback (most recent call last): # File "C:/Python33/test.py", line 17, in <module> # shark.move() # File "C:/Python33/test.py", line 9, in move # self.x -=1 #AttributeError: 'Shark' object has no attribute 'x' ######################################
>>>我要吃了你!
>>>我是位置是 7 0
- 多重继承
class DerivedClassName(Base1 , Base2 , Base 3):
....
虽然python设计了多继承,但是尽量不要使用多继承,容易发生不可预料的问题。
注意: 当多继承时,如果多个父类中有相同的方法名或者属性名,优先调用先继承的父类的方法或者属性
多继承例子:
class Base1: def foo1(self): print("我是foo1,我为Base1代言!") class Base2: def foo2(self): print("我是foo2,我为Base2代言!") class C(Base1 , Base2): pass c = C() c.foo1() c.foo2() >>>我是foo1,我为Base1代言! >>>我是foo2,我为Base2代言!
- 屏蔽父类方法
子类可以用同名的方法覆盖父类的方法,函数体内容写成pass,这样调用该方法就没有任何作用了.
例子:企鹅继承鸟类,但是企鹅不会飞,如果屏蔽父类中鸟儿会飞的方法?
1 class Bird: 2 def fly(self): 3 print("fly away!") 4 5 class Penguin(Bird): 6 def fly(self): 7 pass 8 9 bird = Bird() 10 penguin = Penguin() 11 12 bird.fly() 13 penguin.fly()
>>> fly away!
- 组合
把类的实例化 放到一个新类里面
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 printNum(self): print("水池里面有%d之乌龟和%d只鱼" % (self.turtle.num , self.fish.num)) pool = Pool(10,20) pool.printNum()
>>>水池里面有10之乌龟和20只鱼
- 常用BIF函数
1:issubclass 用于判断一个类是否为另一个类的子类。返回True 或False
class A: pass class B(A): pass print(issubclass(B , A)) # print(issubclass(B , B)) #所有类都认为自己是自己的子类 print(issubclass(B , object)) #所有类都默认集成object类
>>>True
>>>True
>>>True
2:isinstance用于判断一个对象是否某类的一个实例
class A: pass class B(A): pass a=A() print(isinstance(a,(A , B)))
>>>True
3:hasattr(object, name)
判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。需要注意的是name要用括号括起来
>>> class test(): ... name="xiaohua" ... def run(self): ... return "HelloWord" ... >>> t=test() >>> hasattr(t, "name") #判断对象有name属性 True >>> hasattr(t, "run") #判断对象有run方法 True >>>
4:getattr(object, name[,default])
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号。
>>> class test(): ... name="xiaohua" ... def run(self): ... return "HelloWord" ... >>> t=test() >>> getattr(t, "name") #获取name属性,存在就打印出来。 'xiaohua' >>> getattr(t, "run") #获取run方法,存在就打印出方法的内存地址。 <bound method test.run of <__main__.test instance at 0x0269C878>> >>> getattr(t, "run")() #获取run方法,后面加括号可以将这个方法运行。 'HelloWord' >>> getattr(t, "age") #获取一个不存在的属性。 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: test instance has no attribute 'age' >>> getattr(t, "age","18") #若属性不存在,返回一个默认值。 '18' >>>
5:setattr(object, name, values)
给对象的属性赋值,若属性不存在,先创建再赋值。
>>> class test(): ... name="xiaohua" ... def run(self): ... return "HelloWord" ... >>> t=test() >>> hasattr(t, "age") #判断属性是否存在 False >>> setattr(t, "age", "18") #为属相赋值,并没有返回值 >>> hasattr(t, "age") #属性存在了 True >>>
6:delattr
delattr(object, name) 删除object对象名为name的属性
参数object:对象。
参数name:属性名称字符串。
>>> class Person: ... def __init__(self, name, age): ... self.name = name ... self.age = age ... >>> tom = Person("Tom", 35) >>> dir(tom) ['__doc__', '__init__', '__module__', 'age', 'name'] >>> delattr(tom, "age") >>> dir(tom) ['__doc__', '__init__', '__module__', 'name']
7:属性函数(property)
property([fget[, fset[, fdel[, doc]]]])
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() c.getSize() #>>> 10 c1.x #>>> 10 c1.x=18 c1.x #>>> 18 c.getSize() #>>> 18 del c1.x c1.size #AttributeError: 'C' object has no attribute 'size'