面向对象进阶

Posted whylinux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象进阶相关的知识,希望对你有一定的参考价值。

 

  面向对象进阶(1)

# 设计模式
    # 23种
    # 单例模式
        # 限制一个类在程序开始到结束始终只有一个对象实例
        # 当你第一次实例化这个类的时候,就创建一个实例化的对象,但是当你之后再实例化的时候还是就用之前创建的对象


# 实现单例模式,主要用__new__方法,因为__new__是实例化时被第一个运行的函数
class A:
    __instance = False

    def __init__(self, name, age):  # 为__new__创建的对象进行增加属性,还是觉得相当于构造函数
        self.name = name
        self.age = age

    def __new__(cls, *args, **kwargs):  # 创造对应类的对象方法,实例化时最先调用的
        if cls.__instance:  # 如果为True,表示创建过对象,则直接返回这个对象,不在创建
            return cls.__instance
        else:
            cls.__instance = object.__new__(cls)  # 创建一个cls类的对象,返回给cls.__instance
            return cls.__instance   # 返回cls.__instance对象

egon = A(egg, 25)
nezha = A(nazha, 21)
print(egon) # <__main__.A object at 0x00000238A56F30B8>
print(nezha)    # <__main__.A object at 0x00000238A56F30B8>
print(nezha.name)   # nazha
print(egon.name)    # nazha



# __eq__   ==的操作符重载函数,不实现默认比较的是内存地址
class A:
    def __init__(self, name):
        self.name = name

    def __eq__(self, other):    # 当不实现这个内置方法时,obj1和obj2比较的是内存地址,实现后相当于重载了==,根据自己的情况去写。==的操作符重载函数
        #return self == other   # 比较的是内存地址
        if self.name == other.name:
            return True
        else:
            return False

obj1 = A(egg)
obj2 = A(egg)

print(obj1)
print(obj2)
print(obj1 == obj2)


# __hash__
class A:
    def __init__(self, name):
        self.name = name

a = A(why)
b = A(why)
print(hash(a))  # 默认是根据a对象的内存地址进行哈希的
print(hash(b))

class A:
    def __init__(self, name, sex):
        self.name = name
        self.sex = sex

    def __hash__(self): # 如果想要hash一个对象,不想根据对象的内存地址去进行hash,则需要自己去实现一个内置的__hash__方法,不实现,hash对象时默认是对对象的内存地址进行hash
        return hash(self.name + self.sex)

a = A(why, 12)
b = A(why, 12)
print(hash(a))  # 默认是根据a对象的内存地址进行哈希的
print(hash(b))



# 纸牌游戏例子
from collections import namedtuple
import json
Card = namedtuple(Card, [rank, suit])
class FranchDeck:
    ranks = [str(n) for n in range(2, 11)] + list(JQKA)
    suits = [红心, 方板, 梅花, 黑桃]

    def __init__(self):
        self.__cards = [Card(rank, suit) for rank in FranchDeck.ranks
                                        for suit in FranchDeck.suits]

    def __len__(self):
        return len(self.__cards)

    def __getitem__(self, item):
        return self.__cards[item]

    def __setitem__(self, key, value):
        self.__cards[key] = value

    def __str__(self):  # 必须返回str类型的,所以需要序列化
        return json.dumps(self.__cards, ensure_ascii=False) # json序列化(转为字符串),返回

deck = FranchDeck()
print(deck[0])  # 得益于对象实现的__getitem__方法

from random import choice   # 抽取,随机从对象中抽取,抽取的对象必须有len方法,依赖__len__方法,所抽取的对象必须有__len__方法
print(choice(deck)) # 抽牌

from random import shuffle  # 打乱顺序,依赖于__setitem__方法,所打乱的对象必须有__setitem__方法
shuffle(deck)   # 洗牌

print(deck) # 得益于__str__,将所有的牌打印了出来,打印self.__cards列表
print(deck[:5])

# set集合 依赖对象的 hash和eq, set(对象时),目的为了去重,依赖于hash和eq,需重新实现eq和hash

 

以上是关于面向对象进阶的主要内容,如果未能解决你的问题,请参考以下文章

java学习---面向对象进阶

python-前方高能-面向对象-进阶3

python-面向对象进阶

进阶面向对象

python学习笔记-面向对象进阶&异常处理

python学习笔记-面向对象进阶&异常处理