python中类的私有属性和私有方法、类属性和类方法、静态方法、单例设计模式

旧式类(经典类)和新式类

Python中类分两种:旧式类和新式类:
新式类都从object继承,经典类不需要。
新式类是自动调用object类的
python3.几版本后可以自动调用基类(object类)
类的抽象化:类定义之后不调用是没办法输出的。
在Python 3.x中取消了经典类,默认都是新式类,并且不必显式的继承object,也就是说:
class Person(object):pass
class Person():pass
class Person:pass
三种写法并无区别,推荐第一种

但是在Python2.x中,默认都是经典类,只有显式继承了object才是新式类,即:
class Person(object):pass 新式类写法
class Person():pass 经典类写法
class Person:pass 经典类写法

私有属性和私有方法

应用场景及定义方式
应用场景
在实际开发中,对象的某些属性或方法可能只希望在对象内部使用,而不希望在外部被访问到
私有属性就是对象不希望公开的属性
私有方法就是对象不希望公开的方法
定义方法:
例如:

class Women():
    def __init__(self,name):
        self.name = name
        self.__age = 18
    def __secret(self):
        print '%s年龄是%d' % (self.name, self.__age)

lily = Women('lily')
print lily.age
lily.secret()

私有属性私有方法

父类的私有属性和方法

  1. 子类对象不能在自己的方法内部,直接访问父类的私有属性和私有方法
  2. 子类对象可以通过父类的公有方法间接访问到私有属性或私有方法

私有属性,私有方法是对象的隐私,不对外公开,外界以及子类都不能直接访问私有属性,私有方法常用做一些内部的事情
例如:
父类的私有方法、属性

类结构

实例:

  1. 使用面向对象开发,第一步是设计类
  2. 使用类名()创建对象,创建对象的动作有两步

    • 在内存中为对象分配空间
    • 调用__init__初始化方法为对象初始化
  3. 对象创建后,内存中就有了一个对象的实实在在的存在—>实例

因此:

  1. 创建出来的对象叫做类的实例
  2. 创建对象的动作叫做实例化
  3. 对象的属性叫做实例属性
  4. 对象调用的方法叫做实例方法

在程序执行时:

  1. 对象各自调用自己的实例属性
  2. 调用对象的方法,可以通过self
    • 访问自己的属性
    • 调用自己的方法

结论:

  1. 每一个对象有自己独立的内存空间,保存各自不同的属性
  2. 多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的传递到方法内部

类属性

类属性就是针对类对象定义的属性
使用赋值语句在class关键字下方可以定义类属性
类属性用于记录与这个类相关的特性

类是一个特殊的对象
Python中一切皆对象

  • class AAA:定义的类属性属于类对象
  • obj1 =AAA:属于实例对象

在运行程序时,类同样会被家载到内存
在python中,类是一个特殊的对象–类对象

除了封装 实例(对象)的属性和方法外,类对象还可以有自己的属性和方法
通过 类名. 的方式可以直接访问类的属性或者调用类的方法
例如:

class Tool(object):
    # 使用了赋值语句定义类属性,记录所有工具的数量
    count = 0
    def __init__(self, name):
        self.name = name
        # 让类属性的值+1
        Tool.count += 1
# 创建工具对象(对象在创建的时候,会自动调用初始化方法)
tool1=Tool('锤子')
tool2=Tool('斧头')
tool3=Tool('榔头')

# 输出工具对象的总数
# 使用 类名.属性名 来获取
print Tool.count

类属性

类方法

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

语法如下:

@classmethod
def 类方法(cls):
    pass

例如:

class Toy(object):
    # 定义类属性
    count = 0

    @classmethod
    def show_toy_count(cls):
        # cls.count:在类方法的内部,访问当前的类属性
        print '玩具对象的数量 %d' % cls.count
    def __init__(self, name):
        self.name = name
        # 让类属性的值+1
        Toy.count += 1

# 创建玩具对象
toy1 = Toy('乐高')
toy2 = Toy('玩具车')
toy3 = Toy('玩具熊')

# 调用类方法
Toy.show_toy_count()
# 在方法内部,可以直接访问类属性

类方法

静态方法

在开发时,如果需要在类中封装一个方法,这个方法:
既不需要访问实例属性或者调用实例方法
也不需要访问类属性或者调用类方法
这个时候可以把这个方法封装成一个静态方法

语法如下:

@staticmethod
def 静态方法():
    pass

静态方法需要修饰器@staticmethod来标识,告诉解释器这是一个静态方法
通过类名,调用静态方法
例如:

class Cat(object):
    @staticmethod
    def call():
        print 'miaomiao~'

Cat.call()

静态方法

综合应用

需求:
1.设计一个Game类
2.属性
类属性:记录游戏的历史最高分
(与这个游戏有关系,与每次游戏无关)
实例属性:记录当前的游戏玩家
3.方法:
静态方法:方法show_help显示游戏帮助信息
类方法:方法show_top_score显示历史最高分
实例方法:方法start_game开始当前玩家的游戏
4.主程序步骤:
1.查看帮助信息
2.查看历史最高分
3.创建游戏对象,开始游戏

import random
class Game(object):
    high = 0
    def __init__(self, name):
        self.name = name
    @staticmethod
    def show_help():
        print '帮助'
    @classmethod
    def show_top_score(cls):
        print '历史最高分:%d' % cls.high
    def start_game(self):
        print ''
        print '玩家%s开始游戏' % self.name
        score = random.randint(1, 100)
        print '得分:%d' % score
        if score > Game.high:
            Game.high = score
            print '破纪录啦~~~'
        self.show_top_score()

Game.show_help()
Game.show_top_score()
game = Game('player')
game.start_game()
game.start_game()
game.start_game()

结果

案例小结
1.实例方法:方法内部需要访问实例属性
2.类方法:方法内部只需要访问类属性
3.静态方法:方法内部不需要访问实例属性和类属性

提问:如果方法内部,即需要访问实例属性,又需要访问类属性,应该使用哪种方法
应该定义实例方法

单例设计模式

单例:让类创建的对象,在系统中只有唯一的一个实例
例如:
只执行一次初始化工作
在每次使用 类名() 创建对象时,python的解释器都会自动调用两个方法

  • __new__ 分配空间
  • __init__ 对象初始化

需求:让初始化方法只执行一次

class MusicPlayer(object):
    instance = None
    init_flag = False
    def __new__(cls, *args, **kwargs):
        # 第一个参数 cls:哪一个类调用,就传递哪个类
        # 第二个参数 *args:多值参数
        # 第三个参数 **kwargs:多值的字典的参数
        # 创建对象的时候,new方法会被自动调用
        if cls.instance is None:
            cls.instance = object.__new__(cls)
        return cls.instance
    def __init__(self):
        if MusicPlayer.init_flag:
            return
        print '初始化播放器'
        MusicPlayer.init_flag = True
player1 = MusicPlayer()
print player1
player2 = MusicPlayer()
print player2

单例设计模式

猜你喜欢

转载自blog.csdn.net/qq_40303205/article/details/81171525