面向对象是当遇到一个需求的时候不用自己去实现,应该找一个专门做这个事的人来做。如果自己一步步实现那就是面向过程。面向对象 : 采用基于对象(实体) 的概念建立模型,模拟客观世界分析、设 计、实现软件的办法。面向对象编程是一种解决软件复用的设计和编程方法,把软件系统中相近相似的操作逻辑和操作应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,提高软件开发效率。
python几乎所有的都是一个对象,有它的属性和方法。类是用于创建对象的“蓝图”。
类是对一群具有相同特征或者行为的事物的一个统称,不能直接使用;特征被称为属性;行为被称为方法。
对象是由类创建出来的一个具体存在,可以直接使用;由哪一个类创建出来的对象,该对象就具有在那一个类中定义的属性和方法;
二者关系:类就是创建对象的模板,应该先有类,在有对象;一个类可以创建多个对象,不同对象之间属性可能各不相同;类中定义了什么方法,对象中就有什么属性和方法,不可能少,但可能多,因为对象可以自己在类外增加属性。
对象是类的一个实例。它是一个具有状态和行为的实体。简而言之,它是可以访问数据的类的实例。
面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了。
赋值给一个变量
- # 例一
- def dog(name="huang"):
- print(name)
- # 函数对象赋值给变量
- my_dog = dog
- # 变量当函数使用,直接对变量操作也就是对函数操作
- my_dog("wang")
- # 例二
- def dog(name="huang"):
- print(name)
- class Animal:
- def __init__(self): # 初始化函数
- print("huang")
- my_class = Animal
- my_class() # 实例化
-
- 输出:
- wang
- huang
可以添加到集合对象中
- # 例一
- def dog(name="huang"):
- print(name) # None 值,因为没有return
- # return name
- class Animal:
- def __init__(self): # 初始化函数
- print("wang")
- obj_list = []
- obj_list.append(dog)
- obj_list.append(Animal)
- for i in obj_list:
- print(i()) # 类的对象
- # 例二 函数返回函数 装饰器的原理
- def dog(name="huang"):
- print(name) # None 值,因为没有return
- # return name
- class Animal:
- def __init__(self): # 初始化函数
- print("wang")
- def decorator_func():
- print("dec start")
- return dog
- my_animal = decorator_func()
- my_animal("Tom")
-
-
- 输出:
-
- huang
- None
- wang
- <__main__.Animal object at 0x00000229A2087D90>
- dec start
- Tom
常见内置类型
- 对象三个特征:身份(对象在内存中的地址,指针指向对象,eg:a=1 id(a) a={} id(a))、类型、值
- None(全局只有一个)eg:a=None b=None id(a)=id(b)
- 数值:int float complex(复数) bool
- 迭代类型
- 序列类型:list bytes、bytearray、memoryview(二进制序列) range tuple str array
- 映射(dict)
- 集合:set frozenset
- 上下文管理类型(with)
- 其他:模块类型 class和实例 函数类型 方法类型 代码类型 object对象 type类型 ellipsis类型 notimplemented类型
魔法函数
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
-
- animals = Animals(["dog", "cat"])
- animal_name = animals.name
- for i in animal_name:
- print(i)
使用魔法函数__双下划线,python自带,不用自定义,eg:__getitem__,这样直接对animals用for循环就可以了
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
-
- def __getitem__(self, item):
- return self.name[item]
-
- animals = Animals(["dog", "cat"])
- for i in animals:
- print(i)
序列类型,可以用切片的方式
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
-
- def __getitem__(self, item):
- return self.name[item]
-
- animals = Animals(["dog", "cat","pig"])
- animals1= animals[:2]
- for i in animals1:
- print(i)
以上三个例子输出:
dog
cat
len()
- #例一
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
-
- def __getitem__(self, item):
- return self.name[item]
-
- animals = Animals(["dog", "cat","pig"])
- animals1= animals[:2]
- print(len(animals1))
- #输出2
- #例二
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
-
- def __len__(self):
- return len(self.name)
-
- animals = Animals(["dog", "cat","pig"])
- print(len(animals))
- #输出3
魔法函数
非数学运算
- 字符串表示__repr__(开发模式下调用) __str__(字符串格式化的时候调用)
- 集合、序列相关__len__ __getitem__ __setitem__ __delitem__ __contains__
- 迭代相关__iter__ __next__
- 可调用__call__
- With上下文管理器__enter__
- 数值转换__abs__ __bool__ __int__ __float__ __hash__ __index__
- 元类相关__new__ __init__
- 属性相关__getattr__、__setattr__ __getattribute__、__setattribute__ __dir__
- 属性描述符__get__ __set__ __delete__
- 协程__await__ __aiter__ __anext__ __aenter__ __aexit__
- #例一
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
- def __str__(self):
- return ",".join(self.name)
- animals = Animals(["dog", "cat","pig"])
- print(animals)
- animals # 调用__repr__
-
-
- 输出
- dog,cat,pig
- Out[5]:
- <__main__.Animals at 0x2681a154910>
- #例二
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
- def __str__(self):
- return ",".join(self.name)
- def __repr__(self):
- return ",".join(self.name)
- animals = Animals(["dog", "cat","pig"])
- print(animals)
- animals
- # animals.__repr__()#不需要自己调用
-
- 输出
- dog,cat,pig
- Out[6]:
- dog,cat,pig
数学运算
例一__abs__绝对值
- class Nums(object):
- def __init__(self, num):
- self.num = num
- def __abs__(self):
- return abs(self.num)
- my_num = Nums(-1)
- abs(my_num)
- #输出1
pip install ipython
pip install notebook -i https://pypi.tuna.tsinghua.edu.cn/simple
jupyter notebook运行
多态
- # 例一
- class Dog(object):
- def say(self):
- print("dog")
-
- class Cat(object):
- def say(self):
- print("cat")
-
- animals = Dog
- animals().say()
-
- 输出dog
-
- # 例二
- class Dog(object):
- def say(self):
- print("dog")
-
- class Cat(object):
- def say(self):
- print("cat")
-
- animals_list=[Cat,Dog]
- for animal in animals_list:
- animal().say()
-
- 输出
- cat
- dog
-
- # 例三
- class Dog(object):
- def say(self):
- print("dog")
-
- class Cat(object):
- def say(self):
- print("cat")
-
- animals_list=[Cat,Dog]
- for animal in animals_list:
- animal().say()
-
- class Animals(object):
- def __init__(self, name_list):
- self.name = name_list
-
- def __getitem__(self, item):
- return self.name[item]
-
-
- animals = Animals(["dog", "cat","pig"])
- list1=["a","b"]
- list2=["b","c"]
- list3=["d","e"]
- set_list=set()
- set_list.add("f")
- set_list.add("g")
- list1.extend(animals)
- print(list1)
- # extend后面接可迭代的
-
- 输出
- cat
- dog
- ['a', 'b', 'dog', 'cat', 'pig']
-
-
-
- # 例一
- class A:
- def __init__(self):
- print("A")
- class B(A): # B 继承于A
- def __init__(self):
- print("B")
- if __name__ == "__main__":
- b = B()
-
- 输出B
-
- # 例二
- class A:
- def __init__(self):
- print("A")
- class B(A): # B 继承于A
- def __init__(self):
- print("B")
- super().__init__() # super获取到它的父类,调用init函数
- if __name__ == "__main__":
- b = B()
-
- 输出
- B
- A
-
- # 例三
- from threading import Thread
- class MyThread(Thread):
- def __init__(self,name,user):
- self.user=user
- #self.name=name
- super().__init__(name=name)
-
- 例四
- class A:
- def __init__(self):
- print("A")
- class B(A):
- def __init__(self):
- print("B")
- super().__init__()
- class C(A):
- def __init__(self):
- print("C")
- super().__init__()
- class D(B,C):
- def __init__(self):
- print("D")
- super(D,self).__init__() # super调用父类,D有两个BC
-
- if __name__ == "__main__":
- b = D()
-
- 输出
- D
- B
- C
- A
抽象基类
- #例一
- class CacheBase():
- def get(self, key):
- raise NotImplementedError
- def set(self, key, value):
- raise NotImplementedError
- class RedisCache(CacheBase): # RedisCache继承CacheBase
- pass
- redis_cache = RedisCache ()
- redis_cache.set("key", "value")
-
- 输出
- NotImplementedError
-
- #例二
- class CacheBase():
- def get(self, key):
- raise NotImplementedError
- def set(self, key, value):
- raise NotImplementedError
- class RedisCache(CacheBase): # RedisCache继承CacheBase
- def set(self, key, value):
- pass
- redis_cache = RedisCache()
- redis_cache.set("key", "value")
-
- 输出 无,不报错
-
-
- #使用isintance而不是type
- #例三
- class A:
- pass
- class B:
- pass
- b=B()
- print(isinstance(b,B)) # isinstance判断b是不是B的类型
- print(isinstance(b,A)) # isinstance判断b是不是A的类型
- print(type(b) is B)
-
- 输出
- True
- False
- True
类属性和实例属性以及查找顺序
- class D:
- pass
- class C(D):
- pass
-
- class B(D):
- pass
- class A(B,C):
- pass
-
- print(A.__mro__)
- 输出
- (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)
-
- Mro查找
- 自下而上
- class A:
- name="A"
- def __init__(self):
- self.name="obj"
- a=A()
- print(a.name)
- # 自下而上,有下——输出obj
- class A:
- name="A"
- a=A()
- print(a.name)
- #没有下——输出A
-
类变量和对象变量
- 例一:
- class A:
- aa = 1
- def __init__(self, x, y):
- self.x = x
- self.y = y
- a = A(2, 3)
- print(a.x, a.y, a.aa) # 先查对象,再找类
- print(A.aa)
- 输出
- 2 3 1
- 1
- 例二:
- class A:
- aa = 1
- def __init__(self, x, y):
- self.x = x
- self.y = y
- a = A(2, 3)
- A.aa=11
- print(a.x, a.y, a.aa) # 先查对象,再找类
- print(A.aa)
- 输出
- 2 3 11
- 11
- 例三
- class A:
- aa = 1
- def __init__(self, x, y):
- self.x = x
- self.y = y
- a = A(2, 3)
- A.aa=11
- a.aa=100 # 新建a.aa
- print(a.x, a.y, a.aa) # 从下往上,先查对象,再找类
- print(A.aa)
- b=A(3,5)
- print(b.aa)
- 输出
- 2 3 100
- 11
- 11
静态方法、类方法以及对象方法以及参数
- 例一:实例方法
- class Date:
- # 构造函数
- def __init__(self,year,month,day):
- self.year=year
- self.month=month
- self.day=day
-
- def tomorrow(self):#实例方法
- self.day+=1
-
- def __str__(self):
- return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
-
- if __name__=="__main__":
- new_day=Date(2022,5,25)
- new_day.tomorrow()
- print(new_day)
- date_str="2022-5-25"
- year,month,day=tuple(date_str.split("-"))
- new_day=Date(int(year),int(month),int(day))
- print(new_day)
- 输出2022/5/26
- 2022/5/25
-
- 例二:静态方法
- class Date:
- # 构造函数
- def __init__(self,year,month,day):
- self.year=year
- self.month=month
- self.day=day
-
- def tomorrow(self):#实例方法
- self.day+=1
-
- @staticmethod
- def pares_from_string(date_str):
- year, month, day = tuple(date_str.split("-"))
- return Date(int(year), int(month), int(day))
-
- def __str__(self):
- return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
-
- if __name__=="__main__":
- date_str="2022-5-25"
- # 用staticmethod完成初始化
- new_day=Date.pares_from_string(date_str)
- print(new_day)
-
- 例三:类方法
- class Date:
- # 构造函数
- def __init__(self,year,month,day):
- self.year=year
- self.month=month
- self.day=day
-
- @classmethod
- def from_string(cls,date_str):
- year, month, day = tuple(date_str.split("-"))
- return cls(int(year), int(month), int(day))
-
- def __str__(self):
- return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
-
- if __name__=="__main__":
- date_str="2022-5-25"
- # 用classmethod完成初始化
- new_day=Date.from_string(date_str)
- print(new_day)
数据封装和私有属性
- 例一:
- from test1 import Date
- class User:
- def __init__(self,birthday):
- self.birthday=birthday
-
- def get_age(self):
- return 2022-self.birthday.year
-
- if __name__=="__main__":
- user=User(Date(1997,3,1))
- print(user.birthday)
- print(user.get_age())
- 输出1997/3/1
- 25
-
- 例二:
- from test1 import Date
- class User:
- def __init__(self,birthday):
- self.__birthday=birthday #私有属性
-
- def get_age(self):
- return 2022-self.birthday.year
-
- if __name__=="__main__":
- user=User(Date(1997,3,1))
- print(user.__birthday)
- print(user.get_age())
- 输出AttributeError: 'User' object has no attribute '__birthday'
-
- 例三:
- from test1 import Date
- class User:
- def __init__(self,birthday):
- self.__birthday=birthday #私有属性
-
- def get_age(self): # 类的公共的方法可以访问birthday,无法通过实例访问
- return 2022-self.__birthday.year
-
- if __name__=="__main__":
- user=User(Date(1997,3,1))
- print(user.get_age())
- 输出25
-
- 例四:
- from test1 import Date
- class User:
- def __init__(self,birthday):
- self.__birthday=birthday #私有属性
-
- def get_age(self):
- return 2022-self.__birthday.year
-
- if __name__=="__main__":
- user=User(Date(1997,3,1))
- print(user._User__birthday)
- print(user.get_age())
- 输出1997/3/1
- 25
Python对象的自省机制
- 例一:
- class Person:
- "person!"
- name="User"
-
- class Student(Person):
- def __init__(self,school_name):
- self.school_name=school_name
-
- if __name__=="__main__":
- user=Student("小学")
- #通过__dict__查询属性
- print(user.__dict__)
- user.__dict__["school_addr"]="广东"
- print(user.school_addr)
- print(Person.__dict__)
- print(user.name)
-
- 输出:{'school_name': '小学'}
- 广东
- {'__module__': '__main__', '__doc__': 'person!', 'name': 'User', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
- User
-
- 例二:有更详细的对象属性
- class Person:
- "person!"
- name="User"
-
- class Student(Person):
- def __init__(self,school_name):
- self.school_name=school_name
-
- if __name__=="__main__":
- user=Student("小学")
- print(dir(user))
- 输出:['__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']
-
- 例三:
- class Person:
- "person!"
- name="User"
-
- class Student(Person):
- def __init__(self,school_name):
- self.school_name=school_name
-
- if __name__=="__main__":
- user=Student("小学")
- a=[1,2] # list的魔法函数
- print(dir(a))
- 输出:['__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函数
- 例一:
- class A:
- def __init__(self):
- print("A")
-
- class B(A):
- def __init__(self):
- print("B")
-
- if __name__=="__main__":
- b=B()
- 输出B
-
- 例二:
- class A:
- def __init__(self):
- print("A")
-
- class B(A):
- def __init__(self):
- print("B")
- super().__init__() # python 2中:super(B,self).__init__()
-
- if __name__=="__main__":
- b=B()
- 输出B
- A
-
- 例三:
- from threading import Thread
-
- class MyThread(Thread):
- def __init__(self,name,user):
- self.name=name
- self.user=user
- super.__init__(name=name)
-
- class A:
- def __init__(self):
- print("A")
-
- class B(A):
- def __init__(self):
- print("B")
- super().__init__() # python 2中:super(B,self).__init__()
- class C(A):
- def __init__(self):
- print("C")
- super().__init__()
- class D(B,C):
- def __init__(self):
- print("D")
- super(D,self).__init__()
-
- if __name__=="__main__":
- print(D.__mro__)
- b=D()
- 输出:
- (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
- D
- B
- C
- A
上下文管理器协议
- #例一:try except finally
- def exe_try():
- try:
- print ("code started")
- raise KeyError
- return 1
- except KeyError as e:
- print ("key error")
- return 2
- else:
- print ("other error")
- return 3
- finally:
- print ("finally")
- # return 4
-
- if __name__ == "__main__":
- result = exe_try()
- print (result)
-
- 输出:
- code started
- key error
- finally
- 2
- #例二:上下文管理器协议
- class Sample:
- def __enter__(self):
- print ("enter")
- #获取资源
- return self
- def __exit__(self, exc_type, exc_val, exc_tb):
- #释放资源
- print ("exit")
- def do_something(self):
- print ("doing something")
-
- with Sample() as sample:
- sample.do_something()
-
- 输出:
- enter
- doing something
- exit
contextlib简化上下文管理器
- import contextlib
-
- @contextlib.contextmanager
- def file_open(file_name):
- print ("file open")
- yield {}
- print ("file end")
-
- with file_open("bobby.txt") as f_opened:
- print ("file processing")
-
- 输出:
- file open
- file processing
- file end