Python开发第五篇

面向对象程序设计

面向过程编程:就是分析问题的解决步骤,按部就班的编写代码解决问题

函数式编程:就是把代码封装到函数中,然后在使用时调用封装好的函数

面向对象编程:把一类事物所共有的属性和行为提取出来,从而增加程序的扩展性

一、什么是面向对象程序设计?

  面向对象程序设计(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方法
示例代码
原文地址:https://www.cnblogs.com/SunQi-Tony/p/8808944.html