类:相当于一个模子
对象:一个实例
从类到对象实体是一个实例化的过程
类中的属性:静态属性,数据属性(直接和类名相关的变量)
对象属性:在类中和self相关,在类外和对象名相关联
类中的方法:动态属性,函数属性
初始化方法:__init__
self指的是实例化对象本身
class Person():
country = '中国'
def __init__(self, name, age, sex)
self.name = name
self.age = age
self.sex = sex
def walk(self):
print('walking')
ming = Person('小明', 16, '男')
ming.walk() # 相当于Person.walk(ming)
class Person():
country = '中国'
def __init__(self, name):
self.name = name
def walk(self):
print('walk')
alex = Person('alex')
print(alex.__dict__)
print(Person.__dict__)
print(alex.country)
print(Person.country)
alex.country = '美国'
print(alex.country)
print(Person.country)
del alex.country
print(alex.country)
输出结果:
{'name': 'alex'} # 动态属性也是属于类的
{'__module__': '__main__', 'country': '中国', '__init__': <function Person.__init__ at 0x0000019EBC568A60>, 'walk': <function Person.walk at 0x0000019EBC568AE8>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
中国
中国
美国
中国
中国
总结
静态属性:属于类内部的命名空间
class Foo:
country = 'China'
country_lst = ['China']
def__init__(self,name):
self.name = name
alex = Foo('alexander')
egg = Foo('egon')
alex.age = 90
alex.country_lst = []
动态属性:属于类内部的命名空间
对象属性:属于对象的在类内和self发生联系,在类外和对象名发生联系
可以查看静态属性的都有哪些:类名.方法名(对象),对象.方法名()
类到对象之间没有联系,而对象到类之间有联系
对象在查找名的时候,会先在自己的空间里找,再到类的空间里找。
继承
继承是创建新类的方式,新类可以继承一个或多个父类,父类又可以称为基类或者超类,新建的类称为派生类或者子类
class Animal():
pass
class Person(Animal):
pass
Animal就是一个父类,Person就是一个子类
抽象和继承
抽象:从具体到抽象
继承:从抽象到具体
关于子类调用父类的方法
子类对象调用方法如果子类中没有定义就直接找父类的方法进行调用
如果子类对父类的方法进行了覆盖还想调用父类的方法可以有两种调用方式:
1)、 Father.func(子类对象)
2)、 super(Son,self).func()
关于类的继承问题
如果在python2中经典类采用深度优先的查找方式,在新式类中采用基于广度优先的深度优先查找方式。
python3中都是新式类
关于类的派生
在python中自带派生
python不崇尚派生
崇尚鸭子类型:在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
接口类和抽象类
在python中接口类和抽象类都是规范子类的一个模板。接口类和抽象类都不能被实例化。
接口类:支持多继承,在接口类中的属性要尽量的单一,只是定义一个方法名而不去实现它
抽象类:不支持多继承,属性要尽量概括子类的属性,可以有静态属性。
定义接口需要用到abc模块
低级化规范接口方式:
class Fly:
def fly(self): raise NotImplementedError
高端方式引入abc模块
from abc import ABCMeta,abstractmethod
class Fly(metaclass=ABCMeta):
@abstractmethod
def fly(self):pass
class Run(metaclass=ABCMeta):
@abstractmethod
def run(self):pass
class Brid(Fly, Run):
def fly(self):
print('I can fly')
# def run(self):
# print('I can run')
b = Brid()
b.fly()
只要子类中没有实现接口的方法实例化时就抛出异常。