1. 程式人生 > 實用技巧 >Python 內建方法和屬性應用:反射和單例

Python 內建方法和屬性應用:反射和單例

Python 內建方法和屬性應用:反射和單例

  1. 前言

python除了豐富的第三方庫外,本身也提供了一些內在的方法和底層的一些屬性,大家比較常用的如dict、list、set、min、max、range、sorted等。

  1. 內建方法和函式介紹
  • enumerate
    如果你需要遍歷可迭代的物件,有需要獲取它的序號,可以用enumerate, 每一個next返回的是一個tuple
      list1 = [1, 2, 3, 4]
      list2 = [4, 3, 2, 1]
      for idx, value in enumerate(list1):
          print(idx, value, list2[idx])
      # 0 1 4
      # 1 2 3
      # 2 3 2
      # 3 4 1
  • zip zip從引數中的多個迭代器取元素組合成一個新的迭代器;
      # 給list加上序號
      b = [4, 3, 2, 1]
      for i in zip(range(len(b)), b):
          print(i)
      # (0, 4)
      # (1, 3)
      # (2, 2)
      # (3, 1)
  • globals():一個描述當前執行過程中全域性符號表的字典,可以看出你執行的所有過程
  • id(object):python物件的唯一標識
  • staticmethod 類靜態函式註解
      @staticmethod  
      def test(): 
          print('this is static method')
      
      Foo.test = test
      Foo.test()
  • 類的屬性 我們來看下一個類的申明,如下:
      class Foo():
          """this is test class"""
          def __init__(self, name):
              self.name = name
          
          def run(self):
              print('running')
  # 列出類的所有成員和屬性
  dir(Foo)
  ['__class__',
  '__delattr__',
  '__dict__',
  '__dir__',
  '__doc__',
  '__eq__',
  '__format__',
  '__ge__',
  '__getattribute__',
  '__gt__',
  '__hash__',
  '__init__',
  '__init_subclass__',
  '__le__',
  '__lt__',
  '__module__',
  '__ne__',
  '__new__',
  '__reduce__',
  '__reduce_ex__',
  '__repr__',
  '__setattr__',
  '__sizeof__',
  '__str__',
  '__subclasshook__',
  '__weakref__',
  'run']
  
  
  # 類的註釋
  Foo.__doc__
  # 'this is test class'
  
  # 類自定義屬性
  Foo.__dict__
  mappingproxy({'__module__': '__main__',
            '__doc__': 'this is test class',
            '__init__': <function __main__.Foo.__init__(self, name)>,
            'run': <function __main__.Foo.run(self)>,
            '__dict__': <attribute '__dict__' of 'Foo' objects>,
            '__weakref__': <attribute '__weakref__' of 'Foo' objects>})
  
  # 類的父類
  Foo.__base__
  
  # 類的名字
  Foo.__name__

類的例項化和初始化
# python類先通過__new__例項化,再呼叫__init__進行初始化類成員

      foo = Foo('milk')

類的屬性新增和訪問
# 類的訪問

      foo.name
      foo.run()
  # 可以通過setattr 動態的新增屬性
  def method():
      print("cow")
  
  setattr(foo, "type", "cow")
  setattr(foo, "getcow", method)
  # cow
  foo.type
  foo.getcow()
  
  # 動態刪除屬性 delattr
  delattr(foo, "type")
  
  # getattr 獲取成員屬性
  if hasattr(foo, "run"): # 判斷是否有屬性
      func = getattr(foo, "run")
      func()
  1. 單例模式應用

單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。單例模式要求在類的使用過程中只例項化一次,所有物件都共享一個例項。建立的方法是在例項的時候判斷下是否已經例項過了,有則返回例項化過的全域性例項。python是如何實現的呢?關鍵是找到例項化的地方,對就是前面說的__new__

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = object.__new__(cls)
        return cls._instance
    
    def __init__(self, name):
        self.name = name


a = Singleton('name1')
b = Singleton('name2')
print(id(a), id(b))
print(a.name, b.name)
# 1689352213112 1689352213112
# name2 name2
  1. 反射應用

反射在許多框架中都有使用到,簡單就是通過類的名稱(字串)來例項化類。一個典型的場景就是通過配置的方式來動態控制類的執行,比如定時任務的執行,通過維護每個定時任務類的執行時間,在執行時間到的時候,通過反射方式例項化類,執行任務,在java中也非常的常見。

python的實現可以通過上面說的getattr獲取模組中的類, 通過methodcaller來呼叫方法。我們來看一個簡單的例子

import importlib
from operator import methodcaller

class Foo():
    """this is test class"""
    def __init__(self, name):
        self.name = name
    
    def run(self, info):
        print('running %s' % info)

# 類所在的模組,預設情況__main__, 可以通過Foo.__dict__ 中'__module__'獲取
api_module = importlib.import_module('__main__') 
# getattr獲取模組中的類, 這裡Foo是字串哦
clazz = getattr(api_module, 'Foo')

# 例項化
params = ["milk"]
instance = clazz(*params)

# 方法呼叫, 方法也是字串methodcaller(方法名, 方法引數)
task_result = methodcaller("run", "reflection")(instance)

# running reflection
  1. 總結

本文通過分享了python內建方法和屬性, 並在單例模式和反射中進行應用。希望對你有幫助,歡迎交流@mintel 要點總結如下:

  • dir下類
  • 檢視類自定義屬性dict
  • new例項化類,init初始化類
  • getattr 獲取屬性
  • setattr 設定屬性
  • 記住importlib和methodcaller