有很多函数,把这些函数按照一定的关系聚堆,叫做分类
类就是一堆函数的合集
类就是某样东西
这个东西可能是人,有固定的属性,比如名字,生日,身份信息
如果是个活的,还会做出某些行为,就是方法
具体某一个人,这个人就是这个类的对象
类:把一类事物的相同的特征和动作整合到一起就是类
类是一个抽象概念
对象:就是基于类而创建的一个具体的事物
也是特征和动作整合到一起
一、基础
使用函数写一个面向对象设计
def school(name, addr, type):
def init(name, addr, type):
school_attribute = {
"name": name,
"addr": addr,
"type": type,
"exam": exam,
"recruit":recruit}
return school_attribute
def exam(school):
print("%s 正在考试" % name)
def recruit(school):
print("%s 是一所 %s 学校,坐落在 %s" % (name, type, addr))
return init(name, addr, type)
s = school("清华", "北京", "公办")
print(s)
print(s["name"])
s["recruit"](s)
面向对象编程
class 类名:
'类的文档字符串'
类体
class 类名(父类):
'类的文档字符串'
类体
类
变量属性 ==》》数据属性
函数属性 ==》》方法属性
print(dir(classname))
print(classname.__dict__)
__name__
__doc__
__base__
__bases__
__module__
__class__
class Chinese:
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def play_ball(self, ball):
print("%s 正在打 %s" % (self.name, ball))
def __init__(self,xx,xxx,)
self就是实例本身,会自动传给self,
如果类的方法参数中没有self,实例调用该方法,会报错
类具有增删改查
直接=
del
实例有增删改查
可以增加方法,但是只属于自己,不会影响到类
且不会自动把自己传给self
注意:
实例操作类属性时, = 和 append的坑
**********区别:类调用和实例调用*****
二、
静态属性:
@property
@classmethod
@staticmethod
三、
组合
四、
面向对象的三大特性:继承,多态,封装
1、通过封装明确内外
2、通过继承+多态在语言层面支持了归一化设计
抽象/实现
封装/接口
合成
派生/继承/继承结构
泛化/特化
多态
自省/反射
1、
四个可以实现自省的函数(适用于类和对象)
hasattr(object,name)
getattr(object, name, default = None)
setattr(object, name, value)
delattr(object, name)
反射:两个人合作写代码,a负责的模块没写完,b写的块,需要调用a的模块,使用反射,b可以继续写自己的逻辑,不受a没写完的影响。
ex:
if hasattr(object, name):
func_get = getattr(object, name)
func_get
else:
print("还不存在,先继续其他逻辑")
python
1、不完整
module_name = __import__("packge1.modulename")
print(module_name)
module_name.modulename.func()
2、完整
import importlib
module_name = importlib.import_module("packge1.modulename")
print(module_name)
module_name.func()
类内置的的函数属性:(若不重写,系统自己有,若重写,系统调用你定义的)(day26-10-11)
class name:
def __init__(self, xx):
self.xx = xx
def __getattr__(self, item):
print("当获取的属性不存在的时候才会执行此方法, 若存在,就不执行, 不信可以试试")
print("你找的属性 %s 不存在" % item)
def __delattr__(self, item):
print("删除属性的时候会触发,此方法")
self.__dict__.pop(item)
def __setattr__(self, key, value):
print("修改属性时,会执行")
self.__dict__[key] = value
2、继承+派生 ==>> 包装(在子类中重写父类函数)
super()
组合 ==》》》 授权(定制修改,类似于权限管理)
牛逼
五、
isinstance(obj,cls)
issubclass(cls1,cls)
def __getattr__(self,item)
def __getattribute__(self, item)
def __getitem__(self, item)
def __setitem__(self, key, value)
def __delitem__(self, key)
def __str__(self):
return "自定制的对象的输出,print(obj)时调用"
def __rptr__(self):
return "自定制的对象的输出,obj时调用"
def __format__(self, spec):
__slots__ = ["a","b"]
class foo:
'''我是描述信息'''
pass
__doc__
print(func.__module__)
print(func.__class__)
def __del__(self)
def __call__(self, *args, **kwargs)
class foo:
def __init__(self, n)
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.n == 100:
raise StopIteration("抛出异常")
self.n += 1
return slf.n
f = foo()
for i in f:
print(i)
**************重要*************
[参考链接](https://www.cnblogs.com/linhaifeng/articles/6204014.html)
优先级:由高到低
类属性
数据描述符
实例属性
非数据描述符
找不到的属性触发__getattr__()
描述符:__get__ __set__ __delete__
描述符分为数据描述符和非数据描述符。
至少实现了内置__set__()和__get__()方法的描述符称为数据描述符;实现了除__set__()以外的方法的描述符称为非数据描述符。
定义成一个类的类属性
'''
描述符总结:
描述符可以实现大部分python类特性中底层魔法,包括@classmethod @staticmethod @property 甚至是__slots__属性
'''
class Typed:
def __init__(self, key, expectType):
self.key = key
self.expectType = expectType
def __get__(self, instance, owner):
print("get方法")
return instance.__dict__[self.key]
def __set__(self, instance, value):
print("set方法")
if not isinstance(value, self.expectType):
print("typeError 不是字符串类型")
return
instance.__dict__[self.key] = value
def __delete__(self, instance):
print("del方法")
instance.__dict__.pop(self.key)
class People:
name = Typed("name", str)
age = Typed('age', int)
def __init__(self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
p = People("Q", 18, 55.55)
p.name = "h"
print(p.name)
print(p.__dict__)
del p.name
print(p.__dict__)
class Typed:
def __init__(self, key, expectType):
self.key = key
self.expectType = expectType
def __get__(self, instance, owner):
print("get方法")
return instance.__dict__[self.key]
def __set__(self, instance, value):
print("set方法")
if not isinstance(value, self.expectType):
print("typeError 不是字符串类型")
return
instance.__dict__[self.key] = value
def __delete__(self, instance):
print("del方法")
instance.__dict__.pop(self.key)
def deco(**kwargs):
def wrapper(obj):
for key, val in kwargs.items():
setattr(obj, key, Typed(key, val))
return obj
return wrapper
@deco(name = str, age = int, salary = float)
class People:
def __init__(self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
p = People("Q", 18, 55.5)
p.name = 3
print(p.__dict__)
'''
@装饰器name,在执行的时候,被修饰的函数,不被调用,不会执行,但是装饰器会被提前转化
@装饰器放在类里,修饰类的属性时,就等于添加了描述符
区别类调用和实例对象调用
数据描述符和非数据描述符(优先级应用)
\
'''
class selfProperty:
def __init__(self, obj):
print("obj是 %s" % obj)
self.obj = obj
def __get__(self, instance, owner):
print("执行我")
print("instance 是 %s" % instance)
if instance == None:
return self
res = self.obj(instance)
instance.__dict__[self.obj.__name__] = res
return res
class Room:
def __init__(self, width, height):
self.width = width
self.height = height
@selfProperty
def area(self):
return self.width * self.height
r = Room(1,2)
print(r.area)
print(r.area)
print(r.__dict__)
print(Room.area)
print(Room.__dict__)
'''
#xx可以在property修饰的情况下,修改删除
@property
def xx(self):
@xx.setter #依赖上一个
def xx(self,val):
@xx.deleter
def xx(self):
#或者以下方式:
def get_xx(self)
def set_xx(self, val
def del_xx(self)
xx = property(get_xx, set_xx, del_xx) #顺序不能变(获取,设置, 删除)
'''
class People:
def __init__(self, name, age, salary):
self.name = name
self.age = age
self.salary = salary
@property
def name(self):
print("get ----->")
return self.SuiBianQi
@name.setter
def name(self, value):
print("set ------>")
if not isinstance(value, str):
raise TypeError(" %s 不是str类型")
self.SuiBianQi = value
@name.deleter
def name(self):
print("delte ------>")
del self.SuiBianQi
p = People("Q", 18, 55.5)
print(p.name)
print(p.name)
print(p.__dict__)
p.name = "H"
print(p.name)
元类
'''
metaclass
元类是类的类
def __init__(self,name, age):
self.name = name
self.age = age
type("classname",(object,),{key:value,"__init__":__init__})
一个类如果没有声明自己的元类,默认它的元类是type,
除了使用元类type,用户也可以通过继承type类来自定义元类
'''
class Mytype(type):
def __init__(cls, a, b, c):
print("元类的构造函数执行")
def __call__(cls, *args, **kwargs):
obj = object.__new__(cls)
cls.__init__(obj, *args, **kwargs)
return obj
class Foo(metaclass = Mytype):
def __init__(self, name):
self.name = name
f = Foo("Q")
[参考链接](https://www.cnblogs.com/linhaifeng/articles/6182264.html
二、
class Chinese:
li = [1, 2, 3]
__Area = 960
__home = "种花家"
def __init__(self, name, age, gender, city):
self.Name = name
self.Age = age
self.Gender = gender
self.__City = city
def play_ball(self, ball):
print("%s 正在打 %s" % (self.Name, ball))
@property
def length(self):
return len(self.Name)
@classmethod
def tell_info(cls):
print("类方法")
@staticmethod
def wash_face(a, b):
print("%s 和 %s 在洗脸" % (a, b))
def print_hide(self):
print("被隐藏的类属性__Area = %d, 对象属性__City = %s" % (self.__Area, self.__City))
p = Chinese("Q", 18, "male", "jiangsu")
Chinese.addr = "zhongguo"
print(Chinese.addr)
print(Chinese.__dict__)
del Chinese.addr
print(Chinese.__dict__)
p.Phone = 123456
print(p.__dict__)
del p.Phone
print(p.__dict__)
p.li = ["a", "c"]
print(p.__dict__)
print(Chinese.__dict__)
p.li.append("a")
print(p.__dict__)
print(Chinese.__dict__)
del p.li
p.li.append("a")
print(p.__dict__)
print(Chinese.__dict__)
def drink(self,tea):
print("%s喜欢喝 %s" % (self.Name, tea))
Chinese.drink_tea = drink
p.drink_tea("hongcha")
print(Chinese.__dict__)
del Chinese.drink_tea
print(Chinese.__dict__)
p.drink_tea = drink
p.drink_tea(p,"ss")
print(p.__dict__)
del p.drink_tea
print(Chinese.__dict__)
Chinese.play_ball(p, "football")
p.play_ball("basketball")
print(p.length)
Chinese.tell_info()
p.tell_info()
Chinese.wash_face("q", "h")
p.wash_face("q", "H")
p.print_hide()
print(hasattr(p, "Name"))
print(getattr(p, "Age"))
func = getattr(p, "play_ball")
func("basketball")
print(getattr(p, "noAge", "没有这个属性"))
setattr(p, "Age", "22")
print(getattr(p, "Age"))
delattr(p, "Age")
print(hasattr(p, "Age"))
setattr(p, "Age", "18")
print(getattr(p, "Age"))