Python – Introspection

Introspection là một hành động tự kiểm tra. Trong ngôn ngữ lập trình, introspection is khả năng xác định loại hoặc thuộc tính của object tại thời điểm runtime (chạy chương trình). Ngôn ngữ Python support rất nhiều introspection. Mọi thứ (class, function,…) trong Python là 1 object. Mỗi object trong Python có các thuộc tính và phương thức. Bằng việc sử dụng introspection, chúng ta có thể kiểm tra các object Python.

Function dir()

Hàm dir() trả về 1 list sắp xếp gồm các thuộc tính và phương thức của 1 object

Ví dụ 1: hiển thị các thuộc tính và phương thức của object tuple

C:\Users\Dell>python
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> dir(())
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']

In ra thuộc tính ‘__doc__’ của tuple

>>> print(().__doc__)
Built-in immutable sequence.

If no argument is given, the constructor returns an empty tuple.
If iterable is specified the tuple is initialized from iterable's items.

If the argument is a tuple, the return value is the same object.

Ví dụ 2: Kiểm tra các thuộc tính và phương thức của nhiều loại object khác nhau

import sys

class MyObject(object):

   def __init__(self):
      pass

   def examine(self):
      print(self)


o = MyObject()

print(dir(o))
print(dir([]))
print(dir({}))
print(dir(1))
print(dir())
print(dir(len))
print(dir(sys))
print(dir("String"))

Trong ví dụ này, chúng ta in ra nhiều loại object: user defined, native data, function, string.

Nếu gọi hàm dir() không đối số, dir() trả về thuộc tính và phương thức của scope hiện tại

>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> import sys, math
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'math', 'sys']

Chúng ta execute lệnh dir() trước và sau khi import module ‘sys’ và ‘math’.

Function type()

Hàm type() trả về loại object

Ví dụ 3: Kiểm tra loại object

import sys

def function(): 
    pass

class MyObject(object):
    
   def __init__(self):
      pass

o = MyObject()

print(type(1))
print(type(""))
print(type([]))
print(type({}))
print(type(()))
print(type(object))
print(type(function))
print(type(MyObject))
print(type(o))
print(type(sys))

Ví dụ này sẽ in nhiều loại object
Kết quả:

C:\Users\Dell>python test.py
<class 'int'>
<class 'str'>
<class 'list'>
<class 'dict'>
<class 'tuple'>
<class 'type'>
<class 'function'>
<class 'type'>
<class '__main__.MyObject'>
<class 'module'>

Function id()

Hàm id() trả về id của object

Ví dụ 4: In ra id của object

import sys

def fun(): pass

class MyObject(object):
    
   def __init__(self):
      pass

o = MyObject()

print(id(1))
print(id(""))
print(id({}))
print(id([]))
print(id(sys))
print(id(fun))
print(id(MyObject))
print(id(o))
print(id(object))

Ví dụ này sẽ in ra id của các kiểu dữ liệu, function, object class.
Kết quả:
C:\Users\Dell>python test.py
140730581373984
2575863086304
2575863936488
2575863472712
2575863115672
2575863628256
2575861399832
2575864176592
140730580897472

Module ‘sys’

Module ‘sys’ cung cấp quyền truy cập tới các biến và function hệ thống được sử dụng và duy trì bởi trình thông dịch. Module ‘sys’ cho phép chúng ta truy vấn thông tin về môi trường Python.

Ví dụ 5: Kiểm tra version, platform, đường dẫn môi trường Python

C:\Users\Dell>python
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.version
'3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)]'
>>> sys.platform
'win32'
>>> sys.path
['', 'C:\\Users\\Dell\\AppData\\Local\\Programs\\Python\\Python37\\python37.zip', 'C:\\Users\\Dell\\AppData\\Local\\Programs\\Python\\Python37\\DLLs', 'C:\\Users\\Dell\\AppData\\Local\\Programs\\Python\\Python37\\lib', 'C:\\Users\\Dell\\AppData\\Local\\Programs\\Python\\Python37', 'C:\\Users\\Dell\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages']

Ví dụ 6: Kiểm tra executable (đường dẫn thực thi script), argv (tham số truyền vào script), and byteorder (kiến trúc OS là little endian hay big endian

>>> sys.executable
'C:\\Users\\Dell\\AppData\\Local\\Programs\\Python\\Python37\\python.exe'
>>> sys.argv
['']
>>> sys.byteorder
'little'

Other Introspection

Tiếp theo, chúng ta tìm hiểu các introspection khác trong Python.

Ví dụ 7: Function hasattr()

def fun(): 
    pass

print(hasattr(object, '__doc__'))
print(hasattr(fun, '__doc__'))
print(hasattr(fun, '__call__'))

print(getattr(object, '__doc__'))
print(getattr(fun, '__doc__'))

Hàm hasattr() kiểm tra object có thuộc tính X không. Nếu tìm thấy thuộc tính, trả về True.
Hàm getattr() trả về nội dung của thuộc tính nếu tìm thấy trong oject

Kết quả:
C:\Users\Dell>python test.py
True
True
True
The most base type
None

Ví dụ 8: Sử dụng hàm isinstance() kiểm tra object có phải là instance của class hay không

class MyObject(object):
   def __init__(self):
      pass

o = MyObject()

print(isinstance(o, MyObject))
print(isinstance(o, object))
print(isinstance(2, int))
print(isinstance('str', str))

Như chúng ta đã biết, mọi thứ trong Python là object, thậm chí số hoặc string.

Kết quả:
C:\Users\Dell>python test.py
True
True
True
True

Ví dụ 9: sử dụng issubclass() để kiểm tra class có phải là subclass của class khác hay không

class Object(object):  
   def __init__(self):
      pass

class Wall(Object):
   def __init__(self):
      pass

print(issubclass(Object, Object))
print(issubclass(Object, Wall))
print(issubclass(Wall, Object))
print(issubclass(Wall, Wall))

Trong ví dụ, class Wall là subclass của class Object. Object và Wall cũng là subclass của chính nó. Class Object không phải subclass của class Wall

Kết quả:
C:\Users\Dell>python test.py
True
False
True
True

Ví dụ 10: Sử dụng thuộc tính __name__ và __doc__

def noaction():
   '''A function, which does nothing'''
   pass

funcs = [noaction, len, str]

for i in funcs:
    
   print(i.__name__)
   print(i.__doc__)
   print("-" * 75)

Trong ví dụ, chúng ta tạo 1 list 3 function noaction, len và str. Chúng ta duyệt từng phần tử và in ra thuộc tính __name__ và __doc__.
___name__: chứa tên object, __doc__: chứa mô tả về object đó.

Kết quả:
C:\Users\Dell>python test.py
noaction
A function, which does nothing
—————————————————————————
len
Return the number of items in a container.
—————————————————————————
str
str(object=”) -> str
str(bytes_or_buffer[, encoding[, errors]]) -> str

Create a new string object from the given object. If encoding or
errors is specified, then the object must expose a data buffer
that will be decoded using the given encoding and error handler.
Otherwise, returns the result of object.__str__() (if defined)
or repr(object).
encoding defaults to sys.getdefaultencoding().
errors defaults to ‘strict’.
—————————————————————————

Ví dụ 11: Sử dụng callable() để kiểm tra object có phải object callable (function) hay không

class Car(object):
      
    def setName(self, name):
        self.name = name    

def fun():
    pass

c = Car()    
    
print(callable(fun))
print(callable(c.setName))
print(callable([]))
print(callable(1))

Trong ví dụ, kiểm tra 4 object có phải là object callable (function) hay không.

print(callable(fun))
print(callable(c.setName))

Function fun() và phương thức setName() là callable (Phương thức là function liên kết với object)

Kết quả:
C:\Users\Dell>python test.py
True
True
False
False

Be the first to comment

Leave a Reply