2022年 11月 9日

python 面向对象

面向对象是当遇到一个需求的时候不用自己去实现,应该找一个专门做这个事的人来做。如果自己一步步实现那就是面向过程。面向对象 : 采用基于对象(实体) 的概念建立模型,模拟客观世界分析、设 计、实现软件的办法。面向对象编程是一种解决软件复用的设计和编程方法,把软件系统中相近相似的操作逻辑和操作应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,提高软件开发效率。

python几乎所有的都是一个对象,有它的属性和方法。类是用于创建对象的“蓝图”。

是对一群具有相同特征或者行为的事物的一个统称,不能直接使用;特征被称为属性;行为被称为方法。

对象是由类创建出来的一个具体存在,可以直接使用;由哪一个类创建出来的对象,该对象就具有在那一个类中定义的属性和方法;

二者关系:类就是创建对象的模板,应该先有类,在有对象;一个类可以创建多个对象,不同对象之间属性可能各不相同;类中定义了什么方法,对象中就有什么属性和方法,不可能少,但可能多,因为对象可以自己在类外增加属性。

对象是类的一个实例。它是一个具有状态和行为的实体。简而言之,它是可以访问数据的类的实例。

面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了。

赋值给一个变量

  1. # 例一
  2. def dog(name="huang"):
  3. print(name)
  4. # 函数对象赋值给变量
  5. my_dog = dog
  6. # 变量当函数使用,直接对变量操作也就是对函数操作
  7. my_dog("wang")
  8. # 例二
  9. def dog(name="huang"):
  10. print(name)
  11. class Animal:
  12. def __init__(self): # 初始化函数
  13. print("huang")
  14. my_class = Animal
  15. my_class() # 实例化
  16. 输出:
  17. wang
  18. huang 

可以添加到集合对象中

  1. # 例一
  2. def dog(name="huang"):
  3. print(name) # None 值,因为没有return
  4. # return name
  5. class Animal:
  6. def __init__(self): # 初始化函数
  7. print("wang")
  8. obj_list = []
  9. obj_list.append(dog)
  10. obj_list.append(Animal)
  11. for i in obj_list:
  12. print(i()) # 类的对象
  13. # 例二 函数返回函数 装饰器的原理
  14. def dog(name="huang"):
  15. print(name) # None 值,因为没有return
  16. # return name
  17. class Animal:
  18. def __init__(self): # 初始化函数
  19. print("wang")
  20. def decorator_func():
  21. print("dec start")
  22. return dog
  23. my_animal = decorator_func()
  24. my_animal("Tom")
  25. 输出:
  26. huang
  27. None
  28. wang
  29. <__main__.Animal object at 0x00000229A2087D90>
  30. dec start
  31. Tom

常见内置类型

  1. 对象三个特征:身份(对象在内存中的地址,指针指向对象,eg:a=1 id(a) a={} id(a))、类型、值
  2. None(全局只有一个)eg:a=None b=None id(a)=id(b)
  3. 数值:int float complex(复数) bool
  4. 迭代类型
  5. 序列类型:list bytes、bytearray、memoryview(二进制序列) range tuple str array
  6. 映射(dict)
  7. 集合:set frozenset
  8. 上下文管理类型(with)
  9. 其他:模块类型 class和实例 函数类型 方法类型 代码类型 object对象 type类型 ellipsis类型 notimplemented类型

魔法函数

  1. class Animals(object):
  2. def __init__(self, name_list):
  3. self.name = name_list
  4. animals = Animals(["dog", "cat"])
  5. animal_name = animals.name
  6. for i in animal_name:
  7. print(i)

使用魔法函数__双下划线,python自带,不用自定义,eg:__getitem__,这样直接对animals用for循环就可以了

  1. class Animals(object):
  2. def __init__(self, name_list):
  3. self.name = name_list
  4. def __getitem__(self, item):
  5. return self.name[item]
  6. animals = Animals(["dog", "cat"])
  7. for i in animals:
  8. print(i)

序列类型,可以用切片的方式

  1. class Animals(object):
  2. def __init__(self, name_list):
  3. self.name = name_list
  4. def __getitem__(self, item):
  5. return self.name[item]
  6. animals = Animals(["dog", "cat","pig"])
  7. animals1= animals[:2]
  8. for i in animals1:
  9. print(i)

以上三个例子输出:

dog

cat

len()

  1. #例一
  2. class Animals(object):
  3. def __init__(self, name_list):
  4. self.name = name_list
  5. def __getitem__(self, item):
  6. return self.name[item]
  7. animals = Animals(["dog", "cat","pig"])
  8. animals1= animals[:2]
  9. print(len(animals1))
  10. #输出2
  11. #例二
  12. class Animals(object):
  13. def __init__(self, name_list):
  14. self.name = name_list
  15. def __len__(self):
  16. return len(self.name)
  17. animals = Animals(["dog", "cat","pig"])
  18. print(len(animals))
  19. #输出3

魔法函数

非数学运算

  1. 字符串表示__repr__(开发模式下调用)  __str__(字符串格式化的时候调用)
  2. 集合、序列相关__len__       __getitem__    __setitem__    __delitem__    __contains__
  3. 迭代相关__iter__   __next__
  4. 可调用__call__
  5. With上下文管理器__enter__
  6. 数值转换__abs__          __bool__        __int__           __float__         __hash__        __index__
  7. 元类相关__new__         __init__
  8. 属性相关__getattr__、__setattr__        __getattribute__、__setattribute__       __dir__
  9. 属性描述符__get__ __set__ __delete__
  10. 协程__await__       __aiter__         __anext__       __aenter__      __aexit__
  1. #例一
  2. class Animals(object):
  3. def __init__(self, name_list):
  4. self.name = name_list
  5. def __str__(self):
  6. return ",".join(self.name)
  7. animals = Animals(["dog", "cat","pig"])
  8. print(animals)
  9. animals # 调用__repr__
  10. 输出
  11. dog,cat,pig
  12. Out[5]:
  13. <__main__.Animals at 0x2681a154910>
  1. #例二
  2. class Animals(object):
  3. def __init__(self, name_list):
  4. self.name = name_list
  5. def __str__(self):
  6. return ",".join(self.name)
  7. def __repr__(self):
  8. return ",".join(self.name)
  9. animals = Animals(["dog", "cat","pig"])
  10. print(animals)
  11. animals
  12. # animals.__repr__()#不需要自己调用
  13. 输出
  14. dog,cat,pig
  15. Out[6]:
  16. dog,cat,pig

数学运算

例一__abs__绝对值

  1. class Nums(object):
  2. def __init__(self, num):
  3. self.num = num
  4. def __abs__(self):
  5. return abs(self.num)
  6. my_num = Nums(-1)
  7. abs(my_num)
  8. #输出1

pip install ipython

pip install notebook -i https://pypi.tuna.tsinghua.edu.cn/simple

jupyter notebook运行

多态

  1. # 例一
  2. class Dog(object):
  3. def say(self):
  4. print("dog")
  5. class Cat(object):
  6. def say(self):
  7. print("cat")
  8. animals = Dog
  9. animals().say()
  10. 输出dog
  11. # 例二
  12. class Dog(object):
  13. def say(self):
  14. print("dog")
  15. class Cat(object):
  16. def say(self):
  17. print("cat")
  18. animals_list=[Cat,Dog]
  19. for animal in animals_list:
  20. animal().say()
  21. 输出
  22. cat
  23. dog
  24. # 例三
  25. class Dog(object):
  26. def say(self):
  27. print("dog")
  28. class Cat(object):
  29. def say(self):
  30. print("cat")
  31. animals_list=[Cat,Dog]
  32. for animal in animals_list:
  33. animal().say()
  34. class Animals(object):
  35. def __init__(self, name_list):
  36. self.name = name_list
  37. def __getitem__(self, item):
  38. return self.name[item]
  39. animals = Animals(["dog", "cat","pig"])
  40. list1=["a","b"]
  41. list2=["b","c"]
  42. list3=["d","e"]
  43. set_list=set()
  44. set_list.add("f")
  45. set_list.add("g")
  46. list1.extend(animals)
  47. print(list1)
  48. # extend后面接可迭代的
  49. 输出
  50. cat
  51. dog
  52. ['a', 'b', 'dog', 'cat', 'pig']
  53. # 例一
  54. class A:
  55. def __init__(self):
  56. print("A")
  57. class B(A): # B 继承于A
  58. def __init__(self):
  59. print("B")
  60. if __name__ == "__main__":
  61. b = B()
  62. 输出B
  63. # 例二
  64. class A:
  65. def __init__(self):
  66. print("A")
  67. class B(A): # B 继承于A
  68. def __init__(self):
  69. print("B")
  70. super().__init__() # super获取到它的父类,调用init函数
  71. if __name__ == "__main__":
  72. b = B()
  73. 输出
  74. B
  75. A
  76. # 例三
  77. from threading import Thread
  78. class MyThread(Thread):
  79. def __init__(self,name,user):
  80. self.user=user
  81. #self.name=name
  82. super().__init__(name=name)
  83. 例四
  84. class A:
  85. def __init__(self):
  86. print("A")
  87. class B(A):
  88. def __init__(self):
  89. print("B")
  90. super().__init__()
  91. class C(A):
  92. def __init__(self):
  93. print("C")
  94. super().__init__()
  95. class D(B,C):
  96. def __init__(self):
  97. print("D")
  98. super(D,self).__init__() # super调用父类,D有两个BC
  99. if __name__ == "__main__":
  100. b = D()
  101. 输出
  102. D
  103. B
  104. C
  105. A

抽象基类

  1. #例一
  2. class CacheBase():
  3. def get(self, key):
  4. raise NotImplementedError
  5. def set(self, key, value):
  6. raise NotImplementedError
  7. class RedisCache(CacheBase): # RedisCache继承CacheBase
  8. pass
  9. redis_cache = RedisCache ()
  10. redis_cache.set("key", "value")
  11. 输出
  12. NotImplementedError
  13. #例二
  14. class CacheBase():
  15. def get(self, key):
  16. raise NotImplementedError
  17. def set(self, key, value):
  18. raise NotImplementedError
  19. class RedisCache(CacheBase): # RedisCache继承CacheBase
  20. def set(self, key, value):
  21. pass
  22. redis_cache = RedisCache()
  23. redis_cache.set("key", "value")
  24. 输出 无,不报错
  25. #使用isintance而不是type
  26. #例三
  27. class A:
  28. pass
  29. class B:
  30. pass
  31. b=B()
  32. print(isinstance(b,B)) # isinstance判断b是不是B的类型
  33. print(isinstance(b,A)) # isinstance判断b是不是A的类型
  34. print(type(b) is B)
  35. 输出
  36. True
  37. False
  38. True

类属性和实例属性以及查找顺序

  1. class D:
  2. pass
  3. class C(D):
  4. pass
  5. class B(D):
  6. pass
  7. class A(B,C):
  8. pass
  9. print(A.__mro__)
  10. 输出
  11. (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)
  1. Mro查找
  2. 自下而上
  3. class A:
  4. name="A"
  5. def __init__(self):
  6. self.name="obj"
  7. a=A()
  8. print(a.name)
  9. # 自下而上,有下——输出obj
  10. class A:
  11. name="A"
  12. a=A()
  13. print(a.name)
  14. #没有下——输出A

类变量和对象变量

  1. 例一:
  2. class A:
  3. aa = 1
  4. def __init__(self, x, y):
  5. self.x = x
  6. self.y = y
  7. a = A(2, 3)
  8. print(a.x, a.y, a.aa) # 先查对象,再找类
  9. print(A.aa)
  10. 输出
  11. 2 3 1
  12. 1
  13. 例二:
  14. class A:
  15. aa = 1
  16. def __init__(self, x, y):
  17. self.x = x
  18. self.y = y
  19. a = A(2, 3)
  20. A.aa=11
  21. print(a.x, a.y, a.aa) # 先查对象,再找类
  22. print(A.aa)
  23. 输出
  24. 2 3 11
  25. 11
  26. 例三
  27. class A:
  28. aa = 1
  29. def __init__(self, x, y):
  30. self.x = x
  31. self.y = y
  32. a = A(2, 3)
  33. A.aa=11
  34. a.aa=100 # 新建a.aa
  35. print(a.x, a.y, a.aa) # 从下往上,先查对象,再找类
  36. print(A.aa)
  37. b=A(3,5)
  38. print(b.aa)
  39. 输出
  40. 2 3 100
  41. 11
  42. 11

静态方法、类方法以及对象方法以及参数

  1. 例一:实例方法
  2. class Date:
  3. # 构造函数
  4. def __init__(self,year,month,day):
  5. self.year=year
  6. self.month=month
  7. self.day=day
  8. def tomorrow(self):#实例方法
  9. self.day+=1
  10. def __str__(self):
  11. return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
  12. if __name__=="__main__":
  13. new_day=Date(2022,5,25)
  14. new_day.tomorrow()
  15. print(new_day)
  16. date_str="2022-5-25"
  17. year,month,day=tuple(date_str.split("-"))
  18. new_day=Date(int(year),int(month),int(day))
  19. print(new_day)
  20. 输出2022/5/26
  21. 2022/5/25
  22. 例二:静态方法
  23. class Date:
  24. # 构造函数
  25. def __init__(self,year,month,day):
  26. self.year=year
  27. self.month=month
  28. self.day=day
  29. def tomorrow(self):#实例方法
  30. self.day+=1
  31. @staticmethod
  32. def pares_from_string(date_str):
  33. year, month, day = tuple(date_str.split("-"))
  34. return Date(int(year), int(month), int(day))
  35. def __str__(self):
  36. return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
  37. if __name__=="__main__":
  38. date_str="2022-5-25"
  39. # 用staticmethod完成初始化
  40. new_day=Date.pares_from_string(date_str)
  41. print(new_day)
  42. 例三:类方法
  43. class Date:
  44. # 构造函数
  45. def __init__(self,year,month,day):
  46. self.year=year
  47. self.month=month
  48. self.day=day
  49. @classmethod
  50. def from_string(cls,date_str):
  51. year, month, day = tuple(date_str.split("-"))
  52. return cls(int(year), int(month), int(day))
  53. def __str__(self):
  54. return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
  55. if __name__=="__main__":
  56. date_str="2022-5-25"
  57. # 用classmethod完成初始化
  58. new_day=Date.from_string(date_str)
  59. print(new_day)

数据封装和私有属性

  1. 例一:
  2. from test1 import Date
  3. class User:
  4. def __init__(self,birthday):
  5. self.birthday=birthday
  6. def get_age(self):
  7. return 2022-self.birthday.year
  8. if __name__=="__main__":
  9. user=User(Date(1997,3,1))
  10. print(user.birthday)
  11. print(user.get_age())
  12. 输出1997/3/1
  13. 25
  14. 例二:
  15. from test1 import Date
  16. class User:
  17. def __init__(self,birthday):
  18. self.__birthday=birthday #私有属性
  19. def get_age(self):
  20. return 2022-self.birthday.year
  21. if __name__=="__main__":
  22. user=User(Date(1997,3,1))
  23. print(user.__birthday)
  24. print(user.get_age())
  25. 输出AttributeError: 'User' object has no attribute '__birthday'
  26. 例三:
  27. from test1 import Date
  28. class User:
  29. def __init__(self,birthday):
  30. self.__birthday=birthday #私有属性
  31. def get_age(self): # 类的公共的方法可以访问birthday,无法通过实例访问
  32. return 2022-self.__birthday.year
  33. if __name__=="__main__":
  34. user=User(Date(1997,3,1))
  35. print(user.get_age())
  36. 输出25
  37. 例四:
  38. from test1 import Date
  39. class User:
  40. def __init__(self,birthday):
  41. self.__birthday=birthday #私有属性
  42. def get_age(self):
  43. return 2022-self.__birthday.year
  44. if __name__=="__main__":
  45. user=User(Date(1997,3,1))
  46. print(user._User__birthday)
  47. print(user.get_age())
  48. 输出1997/3/1
  49. 25

Python对象的自省机制

  1. 例一:
  2. class Person:
  3. "person!"
  4. name="User"
  5. class Student(Person):
  6. def __init__(self,school_name):
  7. self.school_name=school_name
  8. if __name__=="__main__":
  9. user=Student("小学")
  10. #通过__dict__查询属性
  11. print(user.__dict__)
  12. user.__dict__["school_addr"]="广东"
  13. print(user.school_addr)
  14. print(Person.__dict__)
  15. print(user.name)
  16. 输出:{'school_name': '小学'}
  17. 广东
  18. {'__module__': '__main__', '__doc__': 'person!', 'name': 'User', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
  19. User
  20. 例二:有更详细的对象属性
  21. class Person:
  22. "person!"
  23. name="User"
  24. class Student(Person):
  25. def __init__(self,school_name):
  26. self.school_name=school_name
  27. if __name__=="__main__":
  28. user=Student("小学")
  29. print(dir(user))
  30. 输出:['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get_age', 'name', 'school_name']
  31. 例三:
  32. class Person:
  33. "person!"
  34. name="User"
  35. class Student(Person):
  36. def __init__(self,school_name):
  37. self.school_name=school_name
  38. if __name__=="__main__":
  39. user=Student("小学")
  40. a=[1,2] # list的魔法函数
  41. print(dir(a))
  42. 输出:['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

Super函数

  1. 例一:
  2. class A:
  3. def __init__(self):
  4. print("A")
  5. class B(A):
  6. def __init__(self):
  7. print("B")
  8. if __name__=="__main__":
  9. b=B()
  10. 输出B
  11. 例二:
  12. class A:
  13. def __init__(self):
  14. print("A")
  15. class B(A):
  16. def __init__(self):
  17. print("B")
  18. super().__init__() # python 2中:super(B,self).__init__()
  19. if __name__=="__main__":
  20. b=B()
  21. 输出B
  22. A
  23. 例三:
  24. from threading import Thread
  25. class MyThread(Thread):
  26. def __init__(self,name,user):
  27. self.name=name
  28. self.user=user
  29. super.__init__(name=name)
  30. class A:
  31. def __init__(self):
  32. print("A")
  33. class B(A):
  34. def __init__(self):
  35. print("B")
  36. super().__init__() # python 2中:super(B,self).__init__()
  37. class C(A):
  38. def __init__(self):
  39. print("C")
  40. super().__init__()
  41. class D(B,C):
  42. def __init__(self):
  43. print("D")
  44. super(D,self).__init__()
  45. if __name__=="__main__":
  46. print(D.__mro__)
  47. b=D()
  48. 输出:
  49. (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
  50. D
  51. B
  52. C
  53. A

上下文管理器协议

  1. #例一:try except finally
  2. def exe_try():
  3. try:
  4. print ("code started")
  5. raise KeyError
  6. return 1
  7. except KeyError as e:
  8. print ("key error")
  9. return 2
  10. else:
  11. print ("other error")
  12. return 3
  13. finally:
  14. print ("finally")
  15. # return 4
  16. if __name__ == "__main__":
  17. result = exe_try()
  18. print (result)
  19. 输出:
  20. code started
  21. key error
  22. finally
  23. 2
  1. #例二:上下文管理器协议
  2. class Sample:
  3. def __enter__(self):
  4. print ("enter")
  5. #获取资源
  6. return self
  7. def __exit__(self, exc_type, exc_val, exc_tb):
  8. #释放资源
  9. print ("exit")
  10. def do_something(self):
  11. print ("doing something")
  12. with Sample() as sample:
  13. sample.do_something()
  14. 输出:
  15. enter
  16. doing something
  17. exit

contextlib简化上下文管理器

  1. import contextlib
  2. @contextlib.contextmanager
  3. def file_open(file_name):
  4. print ("file open")
  5. yield {}
  6. print ("file end")
  7. with file_open("bobby.txt") as f_opened:
  8. print ("file processing")
  9. 输出:
  10. file open
  11. file processing
  12. file end