首页 > 代码库 > 面向对象,类
面向对象,类
1、面向对象
2、类,实例
把一个抽象的类的变成一个具体的对象的过程叫实例化,实例化时,python把实例本身传入类的函数中, 类中__init__函数时初始化函数(方法),实例化时,__init__方法自动执行
类本身也是一个内存对象
class student(obect): school = "middle school" # 类变量,在类的内存中 def __init__(self,name,age,sex,major): #初始化 self.name = name # 成员属性或者成员变量,实例化后,在实例的内存空间中 self.age = age self.sex = sex self.major = major
def print_score(self,score): # 类的方法
self.core = score
print (self.core)
st1 = student("px",19,"男","计算机") st2 = student("pz",18,"女","英语")
print (student.school)
print (st1.school)
print (st2.school)
结果为:
middle school
middle school
middle school
实例可以访问类变量,如果实例有和类相同名的变量,实例访问该变量时,该变量的值为实例变量的值,如果实例没有该变量,则为类变量的值。实例变量不能被类访问调用。
类变量,类属性
成员变量,实例变量
3、类的三大特性:
封装:
封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,
对不可信的进行信息隐藏。
多态:
封装和继承都实现了代码重用
多态实现了接口重用,接口统一,
但python没有多态的语法,可以通过一些技巧实现多态的效果:
class Animal(object): def run(self): print ‘Animal is running...‘ class Dog(Animal): def run(self): print ‘Dog is running...‘ class Cat(Animal): def run(self): print ‘Cat is running...‘ def run_twice(animal): animal.run() animal.run()
这样调用run_twice函数时,只要传入的实例是Animal类或Animal子类,都会自动调用实际类型的run方
法
调用方只管调用,不管细节,而当我们新增一种Animal的子类时,只要确保run()方法编写正确,不用管
原来的代码是如何调用的。这就是著名的“开闭”原则:
对扩展开放:允许新增Animal子类;
对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。
继承:
class SchoolMember(object): members = 0 #初始学校人数为0 def __init__(self,name,age): self.name = name self.age = age def tell(self): pass def enroll(self): ‘‘‘注册‘‘‘ SchoolMember.members +=1 print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " %(self.name,SchoolMember.members)) def __del__(self): ‘‘‘析构方法‘‘‘ print("\033[31;1mmember [%s] is dead!\033[0m" %self.name) class Teacher(SchoolMember): def __init__(self,name,age,course,salary): super(Teacher,self).__init__(name,age) self.course = course self.salary = salary self.enroll() def teaching(self): ‘‘‘讲课方法‘‘‘ print("Teacher [%s] is teaching [%s] for class [%s]" %(self.name,self.course,‘s12‘)) def tell(self): ‘‘‘自我介绍方法‘‘‘ msg = ‘‘‘Hi, my name is [%s], works for [%s] as a [%s] teacher !‘‘‘ %(self.name,‘Oldboy‘, self.course) print(msg) class Student(SchoolMember): def __init__(self, name,age,grade,sid): #重写父类的__init__方法 super(Student,self).__init__(name,age) # 同时也继承了父类的_init__方法 self.grade = grade self.sid = sid self.enroll() def tell(self): ‘‘‘自我介绍方法‘‘‘ msg = ‘‘‘Hi, my name is [%s], I‘m studying [%s] in [%s]!‘‘‘ %(self.name, self.grade,‘Oldboy‘) print(msg) if __name__ == ‘__main__‘: t1 = Teacher("Alex",22,‘Python‘,20000) t2 = Teacher("TengLan",29,‘Linux‘,3000) s1 = Student("Qinghua", 24,"Python S12",1483) s2 = Student("SanJiang", 26,"Python S12",1484) t1.teaching() t2.teaching() t1.tell()
python面向对象的高级语法:
在类中可以用装饰器:
1.在类的某个方法之前加了@classmethod后
该方法将会变成类方法,在该方法内部不能访问实例变量
2.在类的某个方法之前加了@staticmethod后
该方法将会变成类静态方法,在该方法内部不能访问实例和类变量
大多数情况没有用,可以使用该类型方法作为类的工具箱
3.在类的某个方法之前加了@property后
该方法将会变成类静态属性,实例只能通过访问属性(变量)的方式访问调用该方法
私有属性:隐藏变量,
不容许在类的外部访问属性(变量),只容许在类内部访问
self.__name = name (加2个下划线就可以变成私有属性)
但是还是有方法可以在外部访问到私有变量的。
d = Animal("Sanjiang")
print (d._Animal__num)
类的特殊成员方法:
1、__doc__
表示类的描述信息
class Foo:
""" 描述类信息"""
def func(self):
pass
print Foo.__doc__
#输出:描述类信息
2、__module__ 和__class__
分别表示
表示当前操作的对象在哪个模块
表示当前操作的对象属于哪个类
from lib.aa import C
obj = C()
print obj.__module__ # 输出 lib.aa,即:输出模块
print obj.__class__ # 输出 lib.aa.C,即:输出类
3 __init__
构造方法,通过类创建对象时,自动触发执行。
4、__del__
对象在内存中销毁后,自动执行程序该方法
5 __call__
class role(object):
def __init__(self):
print (‘__init__‘)
def __call__(self):
print (‘__call__‘)
a = role()
a() # 执行__call__ 方法
6 __new__
是它调用执行__init__
7、__dict__
查看类或对象中的所有成员
8、__str__
如果有定义该方法打印 对象 时,默认输出该方法的返回值。
class Foo: def __str__(self): return ‘pengxuan‘ obj = Foo() print obj # 输出:pengxuan
新式类与经典类:
1、区别一:写法不同
经典类就是老写法
比如以前类的定义类的写法是这样的
class person: def __init__(self,name): self.name = name
而新式类是这样写的
class person(object): def __init__(self,name): self.name = name
区别二:
多继承有区别
class A: def f1(self): print (‘a‘) class B(A): pass class C(A): def f1(self): print (‘C‘) class D(B,C): n = 3 obj = D() obj.f1()
这个例子中如果是广度优先,执行obj.f1()时,从父类查找是否有f1方法的顺序是B->C-A;如果是深度优
先,查找f1方法的顺序是B->A->C。最先在哪个类中找到f1方法,则继承那个类中的f1方法
在低于python3.0的版本
经典类是深度优先
新式类是广度优先
到python3.X版本
新式类和经典类都是广度优先
反射:
hasattr
getattr
setattr
delattr
import sys class WebServer(object): def __init__(self,host,port): # Constructor of the class self.host = host self.port = port def start(self): print("Server is starting...") def stop(self): print("Server is stopping...") def restart(self): self.stop() self.start() def test_run(self,name): print("running...",name,self.host) if __name__ == "__main__": server = WebServer(‘localhost‘,333) server2 = WebServer(‘localhost‘,333) #print(sys.argv[1]) if hasattr(server,sys.argv[1]): func = getattr(server,sys.argv[1]) #获取server.start 内存地址 func() #server.start() #setattr(server,‘run‘,test_run) #server.run(server,‘alex‘) delattr(WebServer,‘start‘) print(server.restart()) #server2.run(server,‘alex‘) ‘‘‘cmd_dic = { ‘start‘:server.start, ‘stop‘:server.stop, }‘‘‘ #if sys.argv[1] == ‘start‘: #if sys.argv[1] in cmd_dic: # cmd_dic[sys.argv[1]]()
面向对象,类