python之面向对象(二)

类属性:

针对类对象定义的属性 使用赋值语句在class关键字下可以定义类属性
当我们定义了一个类属性后,这个属性虽然归类所有,但类的所有实例都可以访问到,当实例并没有该属性,所以会继续查找class的该属性

class fairy:
    name='jing'   #定义类属性

print(fairy.name)
xiannv=fairy()
print(xiannv.name)

jing
jing

千万不要对实例属性和类属性使用相同的名字,因为实例属性优先级高于类属性。相同名称的实例属性将屏蔽掉类属性

class fairy:
    name='jing'   #定义类属性
    def __init__(self,x):
        self.name=x

print(fairy.name)
xiannv=fairy('jj')
print(xiannv.name)

jing
jj

类方法:

针对类对象定义的方法 在类方法内部可以直接访问类属性或者调用其他的类方法

@classmethod
def 方法名称(cls):     ##cls表示调用该方法的类本身
	操作
class fairy:
    name='jing'   #定义类属性
    @classmethod
    def eat(cls):
        print('%s want to eat meat' %(cls.name))

print(fairy.name)
fairy.eat()

jing
jing want to eat meat

———————练习———————

统计创建的玩具数量

class Toy(object):
    # 使用赋值语句定义类属性,记录所有的玩具的数量
    count = 0
    def __init__(self,name):
        self.name = name
        # 让类属性 +1
        Toy.count += 1
    @classmethod
    def show_toy_count(cls):
        print('玩具对象的数量 %d' %(cls.count))
# 创建玩具对象
# toy1 = Toy('乐高')
# toy2 = Toy('泰迪熊')
# 调用类方法
Toy.show_toy_count()

静态方法

如果需要在类中定义一个方法,这个方法,既不需要访问实例属性也不需要调用实例方法;既不需要访问类属性也不需要调用类方法,这个时候就可以把这个方法封装成静态方法。使用@staticmethod关键字进行设置

class Cat(object):
    @staticmethod
    def call():
        print('喵')
# 通过 类名. 调用静态方法
Cat.call()
# 不需要创建对象 直接就可以调用
hk=Cat()
hk.call()

喵
喵

私有属性和私有方法

私有属性:前面带两个下划线表示对变量进行私有化,私有化之后的属性属于类内部的属性,可以在内部进行访问,外部无法随便进行访问或者修改。

私有方法:方法名称前面带两个下划线表示方法私有化,可以在内部进行调用,不能使用实例在外部调用私有化方法。

定义属性或方法
在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法

class Student(object):
    def __init__(self,name,score):
        # 前面带两个下划线表示对变量进行私有化,
        # 外部不能随便的访问和更改
        self.__name = name
        self.__score = score

    def get_grand(self):
        print('my name is %s,my '
              'grade is  %d' %(self.__name,self.__score))

    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score
    def set_name(self,name):
        if isinstance(name,str):
            self.__name = name
        else:
            raise ValueError('请输入正确的名字')
    def set_score(self,score):
        if isinstance(score,int):
            self.__score = score
        else:
            raise ValueError('请输入正确的成绩')

tom = Student('Tom',89)
# print(tom.name)
# print(tom.score)
tom.get_grand()
# print(tom._Student__name)
#tom.__name = 'new name' # 这样做只是给实例添加了__name的属性,并不是
# 修改私有属性变量
tom.set_name(321321)
tom.set_score(90)
print(tom.get_name())
print(tom.get_score())

设计模式——单例

设计模式:

设计模式是前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对某一特定问题的成熟解决方案,使用设计模式是为了可重用代码,让代码更容易被他人理解,保证代码可靠性
单例设计模式:

目的:
让类创建对象,在系统中只有唯一的一个实例,每一次执行类名()返回的对象,内存地址是相同的

使用__new__(cls)方法实现单例设计模式:

我们用 类名. 的方式创建对象的时候,python解释器会帮我们做两件事情,
1.为对象分配空间
__new__是一个由object基类提供的内置的静态方法,主要有两个作用:负责给对象分配空间,并返回对象的引用给初始化方法

2.对象初始化
init(初始化方法)负责给对象初始化.
解释器获得对象的引用后,将引用作为第一个参数,传递给__init__方法

重点

在Python3中,class定义的时候,如果不显式的写继承object,也是会默认自动继承object的,所以也会有__new__(cls)
也就是说在使用类名创建对象的时候,会自动的调用object基类中的__new__(cls)方法生成对象并返回对象的引用。
我们可以在类中对__new__(cls)方法进行重写,使其达到效果是:如果是第一次使用该类创建对象,那就在内存中为对象分配内存空间,并且返回对象的引用,如果已经创建过对象,那就不在重新分配内存空间,直接返回上次创建好的内存空间即可。
所以需要一个类属性来记录是否已经创建过对象,以及存储第一次创建对象时分配的内存地址空间。
重写__new__方法的代码非常固定:
继承自父类方法
返回父类方法调用_new__方法的结果
重写__new__方法一定要return object.new(cls)
否则python的解释器得不到分配了空间的对象引用,就不会调用对象的初始化方法
单例设计模式 示例:

class MusicPlayer(object):
    instance = None
    def __new__(cls, *args, **kwargs):
        print('创建对象 分配空间')
        # 1.创建对象的时候,new方法会被自动调用
        #instance = object.__new__(cls)
        #return instance #返回的是对象的引用
        # 判断类属性是否是空对象
        if cls.instance is None:
            # 调用父类方法 为第一个对象分配空间
            cls.instance = object.__new__(cls)
        return cls.instance

player1 = MusicPlayer()
player2 = MusicPlayer()
player3 = MusicPlayer()
print(player1)
print(player2)
print(player3)

创建对象 分配空间
创建对象 分配空间
创建对象 分配空间
<__main__.MusicPlayer object at 0x7fc6e16e5320>
<__main__.MusicPlayer object at 0x7fc6e16e5320>
<__main__.MusicPlayer object at 0x7fc6e16e5320>
    原文作者:若无其事的苹果
    原文地址: https://blog.csdn.net/qq_36016375/article/details/92794551
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞