• Python双下划线方法和单列模式


    isinstance(obj, cls)方法判断obj是否是cls的对象

    class Foo(object):
        pass
    
    obj = Foo()
    print(isinstance(obj, Foo))   # True

    issubclass(sub, super)判断sub类是否是super类的派生类或子类

    class Foo(object):
        pass
    
    class Bar(Foo):
        pass
    
    print(issubclass(Bar, (Foo,)))     # True

    可以调用类的私有属性

    class Foo(object):
        def __init__(self,name,age):
            self.name = name
            self.__age = age     # 私有方法
    
        def func(self):
            print(self.__age)    # 在当前类中可调用
    
    
    obj = Foo('xiaohei', 50)
    print(obj.name)
    print(obj.__age)         # 拒绝常规方法的调用
    print(obj._Foo__age)     # 强制调用类的私有方法
    obj.func()
    View Code

    Python中设计模式的单列模式

    class Singleton(object):
        """
        Python中设计模式的单列模式
        """
        # 设置类的私有属性即标志位
        __instance = False
    
        def __init__(self, name, age):
            # self是经过cls转化而来
            self.name = name
            self.age = age
    
        def __new__(cls, *args, **kwargs):
            """
            在这里控制对象的创建方式,在内存层面始终指向同一个内存地址即同一对象
            :param cls: 代指当前类
            :param __new__: 构造方法
            :param args:
            :param kwargs:
            """
            if cls.__instance:
                # 再次运行时之前已经生成自己的类,则使用自己的
                return cls.__instance
            Singleton.__instance = object.__new__(cls)
            # 借助object.__new__构造方法,第一次运行时创建一个新对象cls(当前类)
            return Singleton.__instance
    
    
    # 实例化两个对象
    alex = Singleton("Alex", 29)
    # 多设置一个属性
    alex.sex = ""
    jim = Singleton("Jim", 25)
    # <__main__.Singleton object at 0x000001F24903BB70>   一样的内存地址
    # <__main__.Singleton object at 0x000001F24903BB70>
    print(alex)
    print(jim)
    print(alex.name)        # Jim
    print(jim.name)         # Jim 因为是一样的地址,所以同属性会被覆盖
    print(alex.sex)         # 男  后面生成的对象没有这个属性,不会被覆盖
    print(jim.sex)          # 男  因为是一样的地址,所以其他对象有的属性也可以调用

    自己使用双下划线方法制作扑克牌

    import json
    from collections import namedtuple
    # 调用namedtuple()生成Card类
    Card = namedtuple("Card", ["rank", "suit"])      # rank 牌面大小   suit 牌面花色
    
    
    class FranchDeck:
        ranks = [str(i) for i in range(2, 11)] + list("JQKA")     # 设置牌面总数
        suits = ["黑桃", "红心", "梅花", "方块"]                   # 设置花色总数
    
        def __init__(self):
            # 两层for循环生成一副牌
            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):
            return json.dumps(self._cards, ensure_ascii=False)
    
    
    deck = FranchDeck()
    # 调用__getitem__()方法取值
    print(deck[9])
    # 调用父类object的__getattr__()方法获取花色
    print(deck[9].suit)
    from random import choice
    # choice()方法需要知道牌面总数也是__len__()方法
    print(choice(deck))
    from random import shuffle
    # shuffle()方法打乱列表顺序需要__setitem__()方法
    shuffle(deck)
    print(deck[9])
    print(deck)     # 打印字符串的友好方式需要__str__()方法

    使用set()去重对象

    """
    使用set()去重对象
    """
    import json
    
    class People(object):
    
        def __init__(self, name, sex, age):
            self.name = name
            self.sex = sex
            self.age = age
    
        def __eq__(self, other):
            # __eq__ 定义了类的等号(==)行为
            if self.name == other.name and self.sex == other.sex:
                return True
            return False
    
        def __hash__(self):
            return hash(self.name + self.sex)
    
    
    # 生成两个对象
    alex = People("Alex", "", 35)
    alex_one = People("Alex", "", 29)
    # 存储在不同内存地址<__main__.People object at 0x000002972250BB70> <__main__.People object at 0x000002972250BD30>
    print(alex, alex_one)
    # 使用set()去重之后{<__main__.People object at 0x00000120B6E6BB70>}
    # set()对对象操作就需要调用对象的内置方法
    print(set((alex, alex_one)))    # set()依赖的对象方法是 __eq__和__hash__
    alex_two = set((alex, alex_one))
    # 遍历取值会发现取用的还是第一个对象的属性
    for item in alex_two:
        print(item.age)     # 35

    反射(通过字符串的形式操作对象的相关属性)

    class Foo:
        f = '类的静态变量'
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def say_hi(self):
            print('hi,%s'%self.name)
    
    obj=Foo('Peppa', 15)
    
    #检测是否含有某属性
    print(hasattr(obj,'name'))
    print(hasattr(obj,'say_hi'))
    
    #获取属性
    n=getattr(obj,'name')
    print(n)
    func=getattr(obj,'say_hi')
    func()
    
    print(getattr(obj,'aaaaaaaa','不存在啊')) #报错
    
    #设置属性
    setattr(obj,'sb', "Pig")
    setattr(obj,'show_name',lambda self:self.name+'sb')
    print(obj.__dict__)
    print(obj.show_name(obj))
    
    #删除属性
    delattr(obj,'age')
    delattr(obj,'show_name')
    
    print(obj.__dict__)
  • 相关阅读:
    linux驱动启动顺序
    ubuntu下安装UltraEdit
    Linux下安装redis
    IntelliJ IDEA 设置Terminal 窗口字体大小
    centOS安装node
    linux下安装pm2
    nuxt部署在Linux下,ip+端口无法访问到
    var与let、const的区别
    JS函数和箭头函数
    回调函数
  • 原文地址:https://www.cnblogs.com/Guishuzhe/p/9780610.html
Copyright © 2020-2023  润新知