python3中类的使用

本文详细介绍了Python3中的面向对象编程,包括类的创建、类变量、实例变量、私有变量、继承、类方法、静态方法、装饰器、闭包、多态、单例模式等核心概念,并通过示例进行演示。

一、面向对象编程

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

 

 

 

 

 

 

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值