一.类class
在python中所有类也都是默认继承自一个最终基类object
1.构造函数、成员函数、成员变量、局部变量
这几个概念在java中有,在python中也是类似的逻辑,构造函数的函数名是固定的__init__,所有成员变量都写在这个初始化函数中。这个构造函数和java中的有不少区别,这里不详细展开。
类中构造函数和所有成员函数的形参的第一个位置都有一个固定参数,这个参数代表当前对象的引用,像是java中的this,但是通过对象调用函数的时候,不管这个参数,只传需要的实参
class Person:
def __init__(self,name,age): #构造函数
self.name = name #与java不同,python的成员变量写在构造函数
self.age = age
def introduce(this): #成员函数
template = '我的名字是' #局部变量
print(template,this.name) #虽然name是成员变量,但是必须用this.的形式使用
wpw = Person('吴大维',18)
wpw.introduce()
2.类变量、类函数、静态函数
如果像java一样写成员变量,会出现不一样的情况。在class中直接定义的变量,python中叫做类变量。
通过类调用的时候,像是java中的静态变量。
通过对象实例调用的时候,像是成员变量,python的类变量并不是由所有对象共享。
class Person:
appearance = 60 #类变量
Person.appearance = 70
wpw = Person() #实例化后,这个对象就有了自己的appearance变量
print(wpw.appearance) #70
wpw.appearance = 120
print(wpw.appearance) #120
print(Person.appearance) #70
#思考:在class中修改和调用类变量,该怎么做
类函数,用@classmethod修饰符,长得和java中的注解一样。
类函数可以通过类名调用类函数,类函数无法访问对象实体变量,可以访问类变量。
类函数的形参中第一个参数cls,表示该类的一个实例
python中还有静态函数,@staticmethod,静态函数与类函数的区别是,静态函数不在形参中的得到类本身,也无法访问类变量
这两个东西使用起来很像java中的静态函数static
二.访问权限
python中函数和变量默认都是public的,通过变量的特殊命名格式来设置protect和private.
以单下划线开头命名,protected类型
以双下划线开头命名,private类型
python中内置了一种方式来实现java中set和get的设计模式
class Perosn:
def __init__(self,name,age):
self.__name = name #私有变量
self.__age = age
@property #用这个装饰器来声明一个name函数,对象调用的时候相当于get
def name(this)
return this.__name
@name.setter #@property又创建了另一个装饰器@name.setter,相当于set
def name(this,name):
this.__name = name
wpw = Person('吴大维',18)
print(wpw.__name) #AttributeError: 'Person' object has no attribute '__name'
wpw.name = '吴小维' #相当于使用了wpw.name('吴小维')函数,set
print(wpw.name) #相当于使用了wpw.name()函数,get
三.动态绑定函数与属性
def job(n):
print('工作',n,'小时')
wpw = Person('吴大维',18)
wpw.iq= 99 #类中本没有这个属性,单独为这一个对象动态绑定一个新属性
wpw.work = job #为这个对象动态绑定一个新的函数
wpw.work(8)
四.继承与多态
1.多继承
在python中,不存在interface,python像C++一样可以多继承
class ZhiZhangErZhong:
activity = "社会摇"
class Student(Person,ZhiZhangErZhong):
score = 60
def __init__(self,name,age,studentId):
super().__init__(name, age) #父类的构造函数
self.studentId =studentId
def introduce(this): #重写父类的函数
print('我的名字是',this._name,'我的成绩是',this.score,'课间活动',this.activity)
多继承会对代码读写带来麻烦,于是采用mixin设计模式,采用统一的命名规范(如ZhiZhangErZhongMixIn),告诉读代码的人这里不是 is-a 的关系,而是一种组合进来的功能。
python中有抽象方法@abstractmethod
2.重写与重载
python中有重写的概念,和java一样,但是python中没有和java一样的重载
思考:当我在读一段陌生的python代码的时候,我该如何知道一个对象是什么类的对象,有哪些属性,有哪些方法,例如这个里面的dataset,要一层一层的的去找return的源码吗
dataset = datasets.fetch_mldata("MNIST Original")
features = numpy.array(dataset.data, 'int16')
labels = numpy.array(dataset.target, 'int')