类与实例
class Student(object):
pass
- init()方法就是java中的构造器
- 类中的self相当于java中的this,java不用显示声明,python中需要在参数列表中声明
访问限制
- 私有属性用双下划线__开头,只有内部可访问 (private)
- 访问需要类提供get方法,这和java一样
_ 修改就需要set方法 - 实际上,并不是私有的,只是python解释器给属性改了一个名,变为
._类名__属性名
- python中双下划线开头与结尾的,都是特殊变量,一般不能用
- 发现个好玩的,即使类中没有的属性,也是可以xx.xx = xx进行设置的,然后就可以使用了
继承
- 继承会引发多态
- 子类是父类,父类不是子类
- 调用方只管调用,不管细节,无需知道子类型,从而尽可能满足开闭原则
- java是静态语言,它在进行编译的时候就要来检查传入对象的类型是否合法
- Python是动态语言,不需要保证类型完全,只需要它有本方法中需要的方法和属性就ok了
- 鸭子类型,无需严格继承,只要 看起来像鸭子,走起来也像鸭子 就ok
对象信息
- type(obj) 类型,指向函数
- type(obj)
if type(xxx) == type(已知类型)
if type(xxx) == types.FunctionType
判断是否是函数…
- instance(obj,已知类型) 判断类型是否相等
- 返回True or False
- 可用于继承
- 判断是否是其中一种 instance(obj,(xxx,xxx))
- dir(obj) 将所有方法 属性 字符串列表返回
- len(obj) 获取对象的长度
- hasattr(obj,“xxx”) 是否拥有某种属性
- getattr(obj,“xxx”,404) 最后一个参数是默认值,防止不存在报错
- setattr(obj,“xxx”,xx)
- 结合上面的鸭子类型,可以使用对象信息来判断是否像鸭子
实例属性与类属性
- 实例可以任意绑定属性
- 类没有定义name属性,但我可以 实例.name=xxx,然后用
slots
- 作为动态语言,python可以给实例绑定方法与属性
- 而给类动态的绑定,则可以对每个实例都适用,具体操作和实例的绑定一样
- 为了限制绑定,需要
__slots__
- 其作为一个变量,可以定义 允许绑定的 属性名称
- 其他属性是不能够绑定的
- 对继承的子类无效
@property
- 一般的属性都是不对外暴露的,所以需要getter方法,setter方法
- 所以实际上可以使用 @property 来让get方法变成属性,然后使用 @属性.setter 注解setter方法
class Stu(Object):
@property
def score(self):
return self.__score
@score.setter
def score(self,val):
self.__score = val
- 此时就可以直接 xx.属性 进行赋值与调用,不用写get赋值了,方便很多
xx = Stu()
xx.score = css
print(xx.score)
- 原理是装饰器
- 注意 属性的方法名不要与 实际的属性名 相同
- 如果相同,会发生 自环,从而导致无限递归,最终栈溢出
- 注意这里的无论啥方法,名称都要统一,也就是你 注解定义了score,那么所有的方法也得叫score
多重继承
- 多个类别交叉时,就会造成 类的层次复杂
- 这点区别于java,java是单继承,然后使用接口来进行扩展
class Bat(Mammal,FlyableMixIn,XxxMinIn):
pass
- 同时继承多个父类的功能
- 我们可以把继承的第一个类叫做主线,其他额外混入的类,称为MixIn
定制类
- str() 打印实例信息,直接print即可,可自定义
- repr() 打印实例信息,为调试服务
- iter() 实现该方法,返回一个迭代对象,该类可用于 for…in,变成一个Iterable对象
- getitem()可以将类当成list来使用,按下边访问元素
- getattr()当有属性找不到时,python解释器就会调用该方法
- call(),把实例对象当方法使用 xxx() 将对象看做是函数
枚举类
from enum import Enum
@unique
class Weekday(Enum):
Sun = 0
Mon = 1
...
print(Weekday.Mon)
元类
from hello import Hello
h = Hello()
h.hello()
- 其中,Hello是一个class,它的类型是type
- h是Hello的实例,它的类型是Hello
- type()可以返回一个实例的类型: type(obj)
- type()也可以创建新的类型,此时就不需要再 class Hello(object)之类的麻烦定义
- type(class名称,基继承的父类集合(tuple,),方法名)
def function(self):
print("ok")
Hello = type("Hello",(object,),dict(hello=function))
h = Hello()
h.hello()
- metaclass 元类
- 对于类,首先我们定义类,然后创建实例
- metacalss是类的元,先定义metaclass,然后创建类,然后创建实例
- 类是metaclass的实例
- 基本不会用,这个太抽象了,魔术代码