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__)