面向对象程序设计
面向过程编程:就是分析问题的解决步骤,按部就班的编写代码解决问题
函数式编程:就是把代码封装到函数中,然后在使用时调用封装好的函数
面向对象编程:把一类事物所共有的属性和行为提取出来,从而增加程序的扩展性
一、什么是面向对象程序设计?
面向对象程序设计(Object-oriented programming,OOP)是一种程序设计范型,也是一种程序开发方法。将一类事物的动作和特征整合到一起就是面向对象程序设计
二、什么是类?什么是对象?
类:一类事物共有的特征和行为
对象:某个具有类中属性和行为的个体
三、类的声明
1 class Foo(object):#新式类,
2 pass
3
4 class Foo():#经典类
5 pass
6 """
7 在Python 2及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性;反之,即不由任意内置类型派生出的类,则称之为“经典类”。
8
9 “新式类”和“经典类”的区分在Python 3之后就已经不存在,在Python 3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”。
10 """
四、类的属性
数据属性:类中的变量
函数属性:类中定义的方法
五、类内置方法
①__dict__属性字典
对象的属性字典只有数据属性,因为对象之间是共享类的函数属性的
类的属性字典,包括类的数据属性和函数属
1 class Foo(object):
2 x = 10
3 def __init__(self,a):
4 self.a = a
5 def show_a(self):
6 print(self.a)
7
8 f1 = Foo(2)
9 print(f1.__dict__)
10 print(Foo.__dict__)
11
12
13 {'a': 2}
14 {'__module__': '__main__', 'x': 10, '__init__': <function Foo.__init__ at 0x000002A051CC4AE8>, 'show_a': <function Foo.show_a at 0x000002A051CC4B70>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
属性字典
②__name__类名
print(Foo.__name__)
Foo
类名
③__bases__基类
1 class Foo():
2 pass
3
4 class Boo(Foo):
5 pass
6
7 print(Boo.__bases__)#返回元组形式
8
9 (<class '__main__.Foo'>,)
基类名
④__init__() 初始化方法
1 class Foo():
2 def __init__(self):
3 print("创建类对象时执行初始化方法")
4
5 f1 = Foo()#实例化类,也就是创建类对象
6
7 创建类对象时执行初始化方法
初始化方法
六、对象访问类中的变量的顺序
实例化的对象访问类中的变量时,先访问初始化方法init中的属性,如若没有就会访问init方法外的类里的,再没有就会报错
1 class Foo(object):
2 a = 10
3 def __init__(self,a):
4 self.a = a
5
6 f1 = Foo(2)
7 print(f1.a)
8
9
10 2
对象访问类中变量
1 class Foo(object):
2 x = 10
3 def __init__(self,a):
4 self.a = a
5 def show_a(self):
6 print(self.a)
7
8 f1 = Foo(2)
9 print(f1.x)
10
11 10
对象访问变量二
1 class Foo(object):
2 x = 10
3 def __init__(self,a):
4 self.a = a
5 def show_a(self):
6 print(self.a)
7
8 f1 = Foo(2)
9 print(f1.q)
10
11 AttributeError: 'Foo' object has no attribute 'q'
变量不存在报错
七、实例化对象只会保存init方法中的变量,只含有数据属性,需要调用类的函数属性
八、类调用类方法需要指定self参数,参数任意
1 class Foo():
2 def show(self):
3 print("show")
4
5
6 #Foo.show(1)
7 #Foo.show(“sunqi”)
8 #Foo.show([1,2,3])
9
10
11 show
类调用类方法
九、实例增加方法时需要需要传self参数
1 class Foo():
2 def __init__(self,a):
3 self.a = a
4 def show(self):
5 print("show")
6
7 f1 = Foo("111")
8 def hello(self):
9 print("hello")
10
11 f1.fun = hello
12 f1.fun("sss")#必须指定self参数(可以是任意对象)
13 print(f1.__dict__)
14
15 hello
实例增加方法
十、property 方法
property方法会将类中的定义的方法变成变量,直接返回结果,隐藏逻辑
加括号调用时会报错
1 class Foo():
2 def __init__(self,a,b):
3 self.a = a
4 self.b = b
5 # @property
6 def cal(self):
7 return self.a + self.b
8 f1 = Foo(1,2)
9 print(f1.cal)
10
11
12 <bound method Foo.cal of <__main__.Foo object at 0x0000019C642E2128>>
未声明property
1 class Foo():
2 def __init__(self,a,b):
3 self.a = a
4 self.b = b
5 @property
6 def cal(self):
7 return self.a + self.b
8 f1 = Foo(1,2)
9 print(f1.cal)
10
11
12 3
声明property
十一、类方法classmethod
当我们想要用类调用类中定义的方法且不希望指定self对象是,我们就可以 采用classmethod声明一个类方法
1 @classmethod
2 def tell_info(cls,[name,x]):可用更多参数
3 pass
类方法声明
1 class Foo():
2 def func1(self):
3 print("类中的方法")
4
5 @classmethod
6 def func3(cls,x):#类方法cls参数python自动指定类名,其他参数必须传值
7 print("cls--name",cls.__name__)
8 print("-->",x)
9
10
11 f1 = Foo()
12 f1.func3(1)
13 print("*"*10)
14 Foo.func3(1)
15 print(f1.func3)
16 print(Foo.func3)
17
18
19 cls--name Foo
20 --> 1
21 **********
22 cls--name Foo
23 --> 1
24 <bound method Foo.func3 of <class '__main__.Foo'>>
25 <bound method Foo.func3 of <class '__main__.Foo'>>
实例和类调用类方法
十二、静态方法staticmethod
类中的没有修饰符,没有self,没有cls的普通方法实例是不能调用的,因为会默认给该方法穿第一个self参数,会报错
1 class Foo():
2 def func():
3 print("func1")
4 f1 = Foo()
5 f1.func()
6
7 默认传参self
8 TypeError: func() takes 0 positional arguments but 1 was given
实例调用没有任何声明的方法
那么我们如何用实例调用这种方法。这时候就需要用staticmethod声明一个普通方法
1 class Foo():
2 @staticmethod
3 def func():
4 print("func1")
5 f1 = Foo()
6 f1.func()
7
8 func1
staticmethod声明
十三、getattr,hasattr,setattr,delattr反射
1 hasattr(b1,"name") 检测object中有没有一个name字符串对应的属性
2 getattr(b1,"name"),default 得到属性的值,设置default时 即使没有参数不会报错
3 setattr(b1,"name"," ")设置对象属性值,也可以添加函数属性 可以是匿名函数
4 delattr(b1,"name")删除对象的属性
1 class B():
2 c = 1
3 def __init__(self,a,b):
4 self.a = a
5 self.b = b
6 def func(self):
7 print(self.a)
8 print(self.b)
9
10 def fun():
11 print("fun")
12
13 b1 = B(1,2)
14 # print(hasattr(b1,"func"))#判断对象是否有name属性
15 # print(getattr(b1,"func","not exist"))#存在就会返回该对象
16 # print(getattr(b1,"sun","not exist"))#不存在返回设置的默认值
17 # print(getattr(b1,"a"))#1
18 # print(setattr(b1,"func1",lambda x:x+1))
19 # print(setattr(b1,"func1",fun))#增加属性,函数和变量皆可 无返回值
20 # print(b1.__dict__)
21 # delattr(b1,"a")#删除属性
22 # print(b1.__dict__)
23 # print(hasattr(B,"a"))
24 # print(hasattr(B,"func"))
25 # getattr(B,"func")(b1)
26 # print(B.__dict__)
27 # print(getattr(B,"a"))#找不到实例变量
28 # delattr(B,"a")
29 # delattr(B,"c")#可以找到类变量
30 # print(getattr(B,"c","not exist"))
反射示例
十四、__setattr__(),__getattr__(),__delattr__()属性字典操作
1 __setattr__()设置对象属性时会触发setattr,写入属性字典
2 __getattr__()调用一个对象不存在的属性时才会用
3 __delattr__()删除对象属性的时候会触发
4
5 三者都是直接操作属性字典
1 class B():
2 def __init__(self,a,b):
3 self.a = a
4 self.b = b
5 def __setattr__(self, key, value):
6 self.__dict__[key] = value
7 # self.key = value
8 def __getattr__(self, item):
9 print("__getattr__")
10 return "not exist"
11 def __delattr__(self, item):
12 del self.__dict__[item]
13 def func(self):
14 print(self.a+self.b)
15 b1 = B(1,2)
16
17 # print(b1.__dict__)
18
19 # b1.__setattr__("sun","qi")#直接操作属性字典__dict__
20 # print(b1.__dict__)
21 # print(b1.a)#1
22 # print(b1.c)#调用不存在的变量时才会触发getattr方法
23
24
25 # print(b1.__dict__)#{'a': 1, 'b': 2}
26 # b1.__delattr__("a")
27 # print(b1.__dict__)#{''b': 2}
操作属性字典示例
十五、__getitem__(),__setitem__(),__delitem__()中括号调用属性时操作
1 __xxxitem__:使用 [''] 的方式操作属性时被调用
2 __setitem__:每当属性被赋值的时候都会调用该方法,因此不能再该方法内赋值 self.name = value 会死循环
3 __getitem__:当访问不存在的属性时会调用该方法
4 __delitem__:当删除属性时调用该方法
1 class B():
2 c = 1
3 def __init__(self,a,b):
4 self.a = a
5 self.b = b
6 def __getitem__(self, item):
7 print("get %s"%item)
8 return self.__dict__[item]
9 def __setitem__(self, key, value):
10 print("key %s value %s"%(key,value))
11 self.__dict__[key] = value
12 def __delitem__(self, key):
13 print("del %s"%key)
14 del self.__dict__[key]
15
16 b1 = B(1,2)
17 def func():
18 print("func")
19 # print(b1["a"])#访问存在的变量时会调用getitem方法
20 # print(b1["d"])#访问不存在的变量时也会触发getitem方法
21 # b1["d"] = 3#设置属性时会触发setitem方法
22 # b1["func"] = func
23 # print(b1.__dict__)
24 # del b1["a"]
25 # print(b1.__dict__)#删除属性时会触发delitem方法
示例代码