面向对象中的双下划线方法 单例模式 实现一个栈

面向对象中的双下滑方法

  • __new__ 单例模式

    import threading
    
    class Singleton(object):
        _instance = None
        _lock = threading.RLock()
    
        def __new__(cls, *args, **kwargs):
            if cls._instance:
                return cls._instance
            with cls._lock:
                if not cls._instance:
                    cls._instance = super().__new__(cls, *args, **kwargs)
                return cls._instance
    
  • __setitem__ __getitem__ __delitem__ 可以使用 [ ] 赋值

    class Foo(object):
    
        def __setitem__(self, key, value):
            pass
    
        def __getitem__(self, item):
            pass
    
        def __delitem__(self, key):
            pass
    
    obj = Foo()
    
    obj['k1'] = 'value'  # 使用的是 __setitem__
    obj['k1']   #  使用的是 __getitem__
    del obj['k1']  #  使用的是 __delitem__
    
  • __enter__ __exit__ 可以使用 with 语句

    class Foo(object):
    
        def __enter__(self):
            print('进入')
            return 123
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('退出')
    
    obj = Foo()
    with obj as f:
        print(f)
    
    • 实现一个自定义 open
    class MyOpen(object):
    
        def __init__(self, file_path, mode='r', encoding='utf-8'):
            self.file_path = file_path
            self.mode = mode
            self.encoding = encoding
    
        def __enter__(self):
            self.f = open(file=self.file_path, mode=self.mode, encoding=self.encoding)
            return self.f
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            self.f.close()
    
    
    with MyOpen('a.txt', mode='w', encoding='utf-8') as f:
        f.write('写点什么啊 !')
    
  • __call__ 可以

    class Foo(object):
    
        def __call__(self, *args, **kwargs):
            return "value"
    obj = Foo()
    obj()  # value
    # flask源码入口
    
  • __iter__ __next__ 迭代器

    class Iterator(object):
      def __init__(self, data):
          self.data = data
          self.index = 0
    
      def __iter__(self):
          return self
    
      def __next__(self):
          if "__iter__" in dir(self.data):
              if self.index == len(self.data):
                  raise StopIteration
              else:
                  a = self.data[self.index]
                  self.index += 1
                  return a
          else:
              raise StopIteration
    for value in Iterator("22123"):
        print(value)
    

手写栈

class StackFullError(Exception):
    pass
class StackEmptyError(Exception):
    pass
class Stack(object):

    def __init__(self,size):
        self.size = size
        self.index = 0
        self.lis = []


    def push(self,obj):
        if self.index < self.size:
            self.lis.insert(self.index, obj)
            self.index += 1
        else:
            raise StackFullError("装满了")

    def pop(self):
        if self.index > 0:
            self.index -= 1
            return self.lis[self.index]
        else:
            raise StackEmptyError("取完了")

s = Stack(2)

s.push("value_1")
s.push("value_2")
s.push("value_3")
print(s.pop())
print(s.pop())
print(s.pop())
print(s.pop()) # 抛出异常

鸭子模型

class Foo(object):
    def xxxxx(self):
        pass
    
class Base(object):
    def xxxxx(self):
        pass

def func(arg):
    arg.xxxxx()
    
obj1 = Foo()
obj2 = Base()

func(obj1)
func(obj2)

可在循环中删除数据 插入数据 的列表


from collections import Iterable


class MyList(object):

    def __init__(self, iterable):
        self.lst = list(iterable)
        self.len = len(self.lst)
        self.index = 0

    @property
    def to_list(self):
        return self.lst

    def append(self, item):
        self.len += 1
        self.lst.append(item)

    def extend(self, iterable):
        if not isinstance(iterable, Iterable):
            raise TypeError('不是可迭代对象!')
        for item in iterable:
            self.append(item)

    def insert(self, index, obj):
        """
        循环时可插入数据
        :param index:
        :param obj:
        :return:
        """
        self.lst.insert(index, obj)
        if index < 0:
            index = self.len + index
        if self.index != 0 and index < self.index:
            self.index += 1
        self.len += 1

    def remove(self, item):
        """
        循环时可删除数据
        :param item:
        :return:
        """
        self.lst.remove(item)
        self.index -= 1
        self.len -= 1

    def sort(self, key=None, reverse=False):
        self.lst.sort(key=key, reverse=reverse)

    def copy(self):
        return self.lst.copy()

    def clear(self):
        self.lst = []
        self.index = 0
        self.len = 0

    def reverse(self):
        self.lst.reverse()

    def __iter__(self):
        self.index = 0
        return self

    def __next__(self):
        if self.index >= self.len:
            raise StopIteration

        res = self.lst[self.index]
        self.index += 1
        return res

    def __getitem__(self, index):
        return self.lst[index]

    def __setitem__(self, index, item):
        self.lst[index] = item

    def __delitem__(self, index):
        self.remove(self.lst[index])

    def __len__(self):
        return self.len

    def __add__(self, lis: list):
        self.extend(lis)

    def __repr__(self):
        return "{}".format(self.lst)

    __hash__ = None


m = MyList([1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 8, 8, 9])
for i in m:
    if i % 2 == 0:
        m.remove(i)

print(m)

for i in m:
    if i == 3:
        m.insert(6, 122)

print(m)

posted @ 2019-04-23 12:43  拐弯  阅读(276)  评论(0编辑  收藏  举报