python3 面向对象编程
面向对象编程
什么是对象?
一切皆对象;
面向对象是思想:
描述思想的语言有:C++/Java/Python/Swift/C#
两个概念:
类 class
对象 object / 实例 ( instance )
示例:
a = int(100)
b = str("hello")
类的创建语法:
class 类名[ ( 继承列表 ) ]:
‘‘’ 类文档字符串 ‘’’
实例方法(类内的函数method)定义
类变量(class variable) 定义
类方法(@classmethod) 定义
静态方法(@staticmethod) 定义
注:[ ] 的内容可以省略
类的作用:
1,可以用类来创建对象(实例);
2, 类内定义的变量和方法能被此类所创建的所有实例共同拥有;
3, 类通常用来创建具有共同属性的对象(实例);
1 class Dog: 2 pass 3 Dog 4 <class 'Dog'> 5 dir() 6 ['Dog', '__builtins__', 'l', 'sys'] 7 dog1 = Dog() 8 dog1 9 <Dog object at 0x0000000003D4E278> 10 dog1.kinds = "京巴" 11 dog1.color = "白色" 12 print(dog1.kinds, dog1.color) 13 京巴 白色 14 dog1.age = 3 15 dir(dog1) 16 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'color', 'kinds']
实例创建的表达式:
类名([创建传参])
作用: 创建一个类的实例对象并返回实例;
实例说明:
1, 实例有自己的作用域和名字空间,可以为实例添加变量(属性);
2,实例可以调用类中的方法;
3, 实例可以访问类中的类变量;
实例变量:
调用语法: 实例。变量名
在模块中调用: 模块名。实例。变量名
1 class Dog: 2 def infos(self): 3 print("狗的种类:", self.kinds,"狗的颜色", self.color) 4 5 6 dog1 = Dog() 7 dog1.kinds = "京巴" 8 dog1.color = "白色" 9 dog1.infos() #狗的种类: 京巴 狗的颜色 白色
实例方法:
语法:
class 类名(继承列表):
def 实例方法名(self, 形式参数1, 形式参数2.。。。):
'''文档字符串'''
语句。。。
说明:
1, 实例方法是实质是函数,是定义在类内的函数;
2,实例方法属于类的属性;
3, 实例方法的第一个参数代表调用这个实例方法的对象,一般命名为“self”;
4, 实例方法如果没有return语句,则返回None
1 class Dog: 2 "这是一个小动物定义,这种动物属于犬科" 3 def say(self): 4 print("旺!。。。") 5 6 7 import dog 8 dog1 = dog.Dog() 9 dog1.say() #旺!。。。
实例方法的调用语法:
实例。实例方法名(调用参数)
或
类名。实例方法名(实例。调用参数)
dog.Dog.say(dog1)
1 class Dog: 2 "这是一个小动物定义,这种动物属于犬科" 3 def say(self): 4 print("旺!。。。") 5 6 def eat(self, that): 7 "为狗进食,同时在food属性记住吃的什么" 8 print("小狗正在吃:",that) 9 self.food = that 10 11 def food_info(self): 12 """显示小狗进食的信息""" 13 print('小狗吃的是:',self.food) 14 15 def run(self, speed): 16 print("吃了",self.food,"的小狗以",speed, "公里/小时的速度奔跑") 17 18 19 dog1 = Dog() 20 dog1.say() #用对象来调用 21 Dog.say(dog1) #用类来调用 22 # 23 dog1.eat("骨头") 24 print(dog1.food) #骨头 25 dog1.food_info() #小狗吃的是:骨头 26 #创建第二个小狗对象 27 dog2 = Dog() 28 dog2.say() #旺!。。。 29 dog2.eat("狗粮") #小狗正在吃: 狗粮 30 dog2.food_info() #小狗吃的是: 狗粮 31 # 32 dog1.run(20) #吃了 骨头 的小狗以 20 公里/小时的速度奔跑 33 dog2.run(30) #吃了 狗粮 的小狗以 30 公里/小时的速度奔跑
练习1;
1 class Human: 2 3 def setName(self, n): 4 '''添加和修改姓名''' 5 self.name = n 6 7 def setAge(self, a): 8 '''添加和修改年龄''' 9 self.age = a 10 11 def infos(self): 12 '''显示人的信息''' 13 print("姓名:",self.name,"年龄:",self.age) 14 15 p1 = Human() 16 p1.setName("张三") 17 p1.setAge(20) 18 p1.infos() 19 # 20 p2 = Human() 21 p2.setName("李四") 22 p2.setAge(21) 23 p2.infos() 24 #姓名: 张三 年龄: 20 25 #姓名: 李四 年龄: 21
构造方法:
作用:创建对象时初始化实例变量
语法:def __init__(self [ 形式参数列表 ]):
语句。。。
说明:1, 构造方法名必须为 __init__ 不可改变;
2, 在一个类中只能有一个__init__构造方法(有多个时,最后一个起作用)
3,构造方法会在实例创建时自动调用,且将实例自身通过第一个参数self传入__init__方法;
4,构造方法如果没有return语句,则返回self自身;
1 class Dog: 2 def __init__(self, k, c): 3 self.kinds = k 4 self.color = c 5 # return self 6 7 # def __init__(self, *args): 8 # pass 9 10 def setKinds(self, k): 11 self.kinds = k 12 13 def setColor(self, c): 14 self.color = c 15 16 def infos(self): 17 print("狗的种类:", self.kinds,"狗的颜色:", self.color) 18 19 20 dog1 = Dog("京巴","黄色") 21 dog1.infos() #狗的种类: 京巴 狗的颜色: 黄色
析构方法:
语法: class 类名:
def __del__(self ):
pass
作用:1,构造方法会在对象销毁时被自动调用
2,python语言不建议在对象销毁时做任何事,因为此方法的调用时间难以确定;
1 class Dog: 2 def __init__(self, k, c): 3 self.kinds = k 4 self.color = c 5 6 def __del__(self): 7 print("内存释放,数据清除") 8 9 def setKinds(self, k): 10 self.kinds = k 11 12 def setColor(self, c): 13 self.color = c 14 15 def infos(self): 16 print("狗的种类:", self.kinds,"狗的颜色:", self.color) 17 18 19 20 dog1 = Dog("京巴","黄色") 21 dog1 = Dog("aaa","white") #内存释放,数据清除 22 dog1 = None #内存释放,数据清除 23 del dog1 #内存释放,数据清除
练习2
1 class Car: 2 def __init__(self, x, y, z ): 3 self.brand = x 4 self.model = y 5 self.color = z 6 7 def car_it(self, x, y, z): 8 self.brand = x 9 self.model = y 10 self.color = z 11 12 def run(self, s): 13 self.speed = s 14 15 def change_color(self, z): 16 self.color = z 17 18 def infos(self): 19 print("(颜色)",self.color ,"(品牌)",self.brand,"(型号)",self.model,"正在以",self.speed,"km/h的速度行驶。") 20 21 # 22 a4 = Car("奥迪","A4","红色") 23 a4.run(160) 24 a4.infos() 25 #(颜色) 红色 (品牌) 奥迪 (型号) A4 正在以 160 km/h的速度行驶。 26 27 a4.change_color("黑色") 28 a4.run(200) 29 a4.infos() 30 #(颜色) 黑色 (品牌) 奥迪 (型号) A4 正在以 200 km/h的速度行驶。
预置实例属性:
__dict__属性:
每一个对象(实例)都有一个__dict__属性;
__dict__属性绑定一个存储在此实例自身属性的字典;
1 dog1 = Dog() 2 print(dog1.__dict__) 3 {'color':'white', 'kinds':'京巴'} 4 dog1.__dict__
__doc__属性:
用于保存类的文档字符串,用于help()中显示,实例的文档字符串和类的文档字符串相同;
1 dog1 = Dog 2 help(Dog) 3 help(dog1) 4 dog1.__doc__
__class__属性
__class__属性绑定创建此对象(实例)的类对象(类实例);
作用:1, 可以借助于此属性来创建同类的实例;
2, 可以借助于此属性来访问类变量
1 import dog 2 dog.dog1 3 dog.dog1.infos() 4 dog.dog1.__class__ 5 <class 'dog.Dog'>
1 dog2 = dog2.dog1.__class__( "大型犬", "黄色" ) 2 3 dog2.infos() 4 5 品种: "大型犬" 颜色 "黄色" 6 7 #=== 8 L=[1,2,3] 9 L.__class__ 10 <class 'list'> 11 L.__class__(range(10)) 12 [0,1,2,3,4,5,6,7,8,9] 13 list(range(10))
__module__属性
绑定此实例所属的模块;
在主模块中,此值为‘__main__’
不在主模块中,此值为模块名;
1 class Human: 2 pass 3 4 h1 = human() 5 h1.__module__ 6 #'__main__'
类变量
1,是指在类class 内定义的变量, 此变量属于类,不属于此类的对象(实例)
2,类变量, 可以通过该类直接使用;
3,类变量,可以通过类的实例直接调用
4, 类变量可以通过此类的对象的__class__属性间接访问;
1 class Human: 2 home = "地球" 3 def __init__(self, name): 4 self.name = name 5 6 7 #print(home) #错的 8 print(Human.home) #地球 9 h1 = Human("张三") 10 print(h1.home) #访问类对象 11 h1.home = "火星" #为此类添加了实例属性 12 print(h1.home) #火星 访问实例属性 13 print(Human.home) #???? 访问类属性 #地球
1 class Human: 2 home = "地球" 3 def __init__(self, name): 4 self.name = name 5 6 7 #print(home) #错的 8 print(Human.home) #地球 9 h1 = Human("张三") 10 print(h1.home) #访问类对象 11 h1.home = "火星" #为此类添加了实例属性 12 print(h1.home) #火星 访问实例属性 13 print(Human.home) #???? 访问类属性 #地球 14 # 15 print(h1.__class__.home) # 间接访问类变量 # 地球 16 # 17 h1.__class__.home = "月球" 18 print(Human.home) #月球 19 # 20 h2 = Human("张三") 21 print(h2.home) #月球
类的__slots__属性
作用:1,限定一个类创建的实例只能有固定的实例属性,不允许对象添加列表以外的实例属性;
2, 防止用户因为错写属性名儿发生程序错误
说明: __slots__属性是一个列表,里边的值是字符串含有__slots__属性的类所创建的实例对象没有__dict__属性,即,此实例不用字典来存储属性;
1 class Student: 2 3 __slots__ = ["name","age","score"] 4 5 def __init__(self, n, a ,s): 6 self.name, self.age, self.score = n, a, s 7 8 9 s1 = Student("xixi", 20, 90) 10 print(s1.score) #90 11 s1.score = 92 12 print(s1.score) #92 13 #s1.Score = 100 #注意 score 和Score 不同 #AttributeError: 'Student' object has no attribute 'Score' #y因为有__slots__属性而报错 14 print(s1.score) #92
对象的属性管理:
函数:
getattr(object, name[, default]) -> value
说明: 从一个对象得到对象的属性,getattr(x,‘ y ’)等同于x.y ; 当属性不存在时,如果给出default参数,则返回default,如果没有给出default则产生一个AttributeERROR错误;
hasattr(object, name) -> bool
说明:用给定的name返回对象obj是否有此属性,此做法可以避免getattr() 函数引发错误;
setattr(object, name, value)
说明:给对象object的名为name的属性设置相应的值,set(x, ‘ y ’, v)等同于x.y = v ;
delattr(object, name)
说明:删除对象obj的name属性,delattr(x,‘ y ’) 等同于del x.y ;
1 >>> class Myclass: 2 pass 3 4 >>> obj = Myclass() 5 >>> dir(obj) 6 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] 7 >>> obj.__class__ 8 <class '__main__.Myclass'> 9 >>> obj.a1 = 100 10 >>> obj.__dict__ 11 {'a1': 100} 12 >>> setattr(obj, 'a2', 200) 13 >>> obj.__dict__ 14 {'a2': 200, 'a1': 100} 15 >>> hasattr(obj, 'a1') 16 True 17 >>> hasattr(obj, 'a2') 18 True 19 >>> hasattr(obj, 'a3') 20 False 21 >>> getattr(obj, 'a1') 22 100 23 >>> getattr(obj, 'a2') 24 200 25 >>> getattr(obj, 'a3') 26 Traceback (most recent call last): 27 File "<pyshell#15>", line 1, in <module> 28 getattr(obj, 'a3') 29 AttributeError: 'Myclass' object has no attribute 'a3' 30 >>> getattr(obj, 'a3', 0) 31 0 32 >>> obj.__dict__ 33 {'a2': 200, 'a1': 100} 34 >>> delattr(obj, 'a1') 35 >>> obj.__dict__ 36 {'a2': 200} 37 >>> del obj.a2 38 >>> obj.__dict__ 39 {} 40 >>>
用于类的函数:
isinstance(obj , 类或类的元组) 返回这个对象obj是否为某个类或某些类的对象, 如果是返回True, 否则返回False ;
type(obj) 返回对象的类型;
1 class A: 2 pass 3 4 5 a = A() 6 def fn(x): 7 #我们不知道x绑定是什么类型? 8 if isinstance(x,A): 9 print('x是一个A类型的对象') 10 elif isinstance(x, int): 11 print("x为整数") 12 13 14 fn(1) #x为整数 15 fn(a) #x是一个A类型的对象 16 fn([1,2,3]) 17 if type(a) == A: 18 print("a是A类型的对象") 19 20 ############## 21 >>> class A: 22 pass 23 24 >>> a = A() 25 >>> isinstance(a, int) 26 False 27 >>> isinstance(a, A) 28 True 29 >>> isinstance(a, str) 30 False 31 >>> isinstance(a, (str, int, bool)) 32 False 33 >>> isinstance(a, (str, int, bool, A) 34 ) 35 True 36 >>> type(a) 37 <class '__main__.A'> 38 >>> type(a) == A 39 True 40 >>> type(a) 41 <class '__main__.A'> 42 >>> type(a)() #A() 43 <__main__.A object at 0x00000000036D1D68> 44 >>> type(1) 45 <class 'int'> 46 >>> type('q') 47 <class 'str'> 48 >>> type('1+1j') 49 <class 'str'> 50 >>> type((1)) 51 <class 'int'> 52 >>> type((1,)) 53 <class 'tuple'> 54 >>> type({}) 55 <class 'dict'> 56 >>> type({1,2,3}) 57 <class 'set'> 58 >>> type({'a':1,'b':2,'c':3}) 59 <class 'dict'> 60 >>>