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