一、面向对象编程
1.1 面向对象编程好处
减少重复代码编写,可以更好的进行程序的维护、扩展、升级
函数式编程和面向对象编程区别:
函数式编程:没法保存数据;各个函数之间是独立且无共用的数据
面向对象编程:对特定数据进行维护和管理;各个函数共用一组数据
1.2 类的特征
第一,具有属性(状态),比如人的个数
第二,具有方法,改变状态的方法,比如改变人的个数
1.3 生成一个学生的类
class Student(object):
def __init__(self,name,age,grade,course=[],course_grade={}):
self.name=name
self.age=age
self.grade=grade
self.course=course
self.course_grade=course_grade
def get_age(self):
return self.age
def set_age(self,age):
self.age=age
return self.age
def get_course(self):
print(self.course)
def set_course(self,course):
self.course=course
def get_course_grade(self):
for k,v in self.course_grade.items():
print(k,v)
def set_course_grade(self,course,grade):
if course not in self.course:
return 0
else:
self.course_grade[course]=grade
return 1
if __name__=="__main__":
s1=Student("xiaoming",10,"三年级")
print(s1.get_age())
print(s1.set_age(20))
print(s1.get_course())
print(s1.get_course_grade())
print(s1.set_course(["语文","数学","外语"]))
print(s1.get_course())
print(s1.set_course_grade("语文",100))
print(s1.set_course_grade("外语",120))
print(s1.set_course_grade("历史",100))
print(s1.get_course_grade())
1.4 类变量
class Student(object):
student_num=0
def __init__(self,name,age,grade,course=[],course_grade={}):
self.name=name
self.age=age
self.grade=grade
self.course=course
self.course_grade=course_grade
Student.student_num+=1
def get_student_num(self):
return Student.student_num
if __name__=="__main__":
s1=Student("xiaoming",10,"三年级")
print(s1.get_student_num())
1.3.1 类变量的修改
class Student(object):
student_num=0
def __init__(self,name,age,grade,course=[],course_grade={}):
self.name=name
self.age=age
self.grade=grade
self.course=course
self.course_grade=course_grade
Student.student_num+=1
def get_student_num(self):
return Student.student_num
if __name__=="__main__":
s1=Student("xiaoming",10,"三年级")
Student.student_num=100
print(s1.get_student_num())
1.3.2 类变量和实例变量的区别
类变量:声明在实例方法外面,通过 类名.类变量 或者 实例变量.类变量 调用
实例变量:声明在实例方面里面,并且带有self,通过 实例名.实例变量 调用
1.5 私有变量
class Student(object):
__student_num=0
def __init__(self,name,age,grade,course=[],course_grade={}):
self.name=name
self.age=age
self.grade=grade
self.course=course
self.course_grade=course_grade
Student.__student_num+=1
def get_student_num(self):
return Student.__student_num
if __name__=="__main__":
s1=Student("xiaoming",10,"三年级")
Student.__student_num=100
print(s1.get_student_num())
1.6 继承
class Student(object):
student_num=0
def __init__(self,name,age):
self.name=name
self.age=age
Student.student_num+=1
def get_student_num(self):
return Student.student_num
def get_name(self):
return self.name
class Teacher(Student):
def __init__(self,name,age,subject):
self.subject=subject
Student.__init__(self,name,age)
def get_subject(self):
return self.subject
if __name__=="__main__":
t1=Teacher("xiaoming",12,"英语老师")
print(t1.get_name())
print(t1.get_subject())
好处: 基于原有类进行扩展
1.7 类方法
class P(object):
@classmethod
def print_str(cls,content):
return content
if __name__=="__main__":
print(P.print_str("hello"))
p=P()
print(p.print_str("hi"))
1.8 静态方法
class P(object):
@staticmethod
def print_str(content):
return content
if __name__=="__main__":
print(P.print_str("hello"))
p=P()
print(p.print_str("hi"))
1.9 装饰器
class Goods(object):
def __init__(self):
self.value=1
@property
def price(self):
return self.value
@price.setter
def price(self,value):
self.value=value
@price.deleter
def price(self):
del self.value
if __name__=="__main__":
obj=Goods()
#自动执行@property修饰的方法price方法
print(obj.price)
#自动执行@property.setter修饰的price方法
obj.price=123
print(obj.price)
#自动执行@property.deleter修饰的price方法
del obj.price
print(obj.price)
好处:给所有函数增加一下附加的功能
1.10 闭包
def outer(name):
def inner():
print(name)
return inner
p=outer("python")
p()
print(p.__closure__)
闭包:返回一个函数,以及执行这个函数所需要的变量
1.11 多态
同一个方法,依据参数不同,表现结果不一样,这种方式叫做多态。
def add(x,y):
return x+y
print(add(1,2))
print(add("hello","world"))
print(add(1,"abcd"))
1.12 重写
class Parent(object):
def myMethod(self):
return "call Parent"
def printName(self):
return "my name is Lily"
class Child(Parent):
def myMethod(self):
Parent.myMethod(self)
return "call Child"
#子类实例
c=Child()
#子类调用重写方法
print(c.myMethod())
#子类调用从父类继承来的方法
print(c.printName())

1.12 单例
确保一个类只有一个实例存在
应用场景:
服务器有一个配置文件,客户端A访问时需要读取,生成一个实例;客户端B访问时也需要读取,又生成一个实例,这样严重浪费内存资源;我们希望只生成一个实例,供其他对象使用。
1.12.1 单例的三个要点
第一,一个类只能生成一个实例
第二,必须自行创建这个实例
第三,必须自行向整个系统提供这个实例
1.12.2 实现单例的四种方法
第一,使用模块
第二,使用__new__
第三,使用装饰器
第四,使用元类
1.12.2.1 使用模块
python的模块就是天然的单例模式。因为模块第一次导入时,会生成.pyc文件,当第二次导入时,就会之间加载.pyc文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象。
#test.py文件
class Myclass(object):
def foo(self):
print('MyClass.foo')
my_class_obj=MyClass()
如何使用
from test import my_class_obj
my_class_obj.foo()
1.12.2.2 使用__new__
使用__new__来控制实例的创建过程
class Singleton(object):
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig = super(Singleton, cls)
cls._instance = orig.__new__(cls, *args, **kw)
return cls._instance
class MyClass(Singleton):
a = 1
one = MyClass()
two = MyClass()
print(one==two)
print(id(one),id(two))
1.12.2.3 使用装饰器
装饰品可以动态地修改一个类或函数的功能,我们也可以使用装饰器来装饰某个类,使其只能生成一个实例。
from functools import wraps
def singleton(cls):
instance={}
@wraps(cls)
def getinstance(*args,**kwargs):
if cls not in instances:
instances[cls]=cls(*args,**kwargs)
return instances[cls]
return getinstance
@singleton
class MyClass(object):
a=1
备注:
我们定义了一个装饰器singleton,它返回了一个内部函数getinstance,该函数会判断某个类是否存在字典instances中。
如果不存在,则会将cls作为key,cls(*args,**kw)作为value存到instances中,否则,直接返回instances[cls]
1.12.2.4 使用metaclass
元类(metaclass)可以控制类的创建过程,它主要做三件事:
第一,拦截类的创建
第二,修改类的定义
第三,返回修改后的类
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
# Python2
# class MyClass(object):
# __metaclass__ = Singleton
# Python3
class MyClass(metaclass=Singleton):
pass
本文详细介绍了Python3中的面向对象编程,包括类的创建、类变量、实例变量、私有变量、继承、类方法、静态方法、装饰器、闭包、多态、单例模式等核心概念,并通过示例进行演示。
11万+

被折叠的 条评论
为什么被折叠?



