Trong lập trình hướng đối tượng, reflection đề cập đến khả năng trích xuất thông tin về bất kỳ đối tượng nào đang được sử dụng. Bạn có thể biết loại đối tượng, liệu nó có phải là lớp con của bất kỳ lớp nào khác không, các attributes của nó là gì, và nhiều hơn nữa. Thư viện chuẩn của Python có nhiều hàm phản ánh các thuộc tính khác nhau của một đối tượng. Reflection cũng đôi khi được gọi là introspect .
Dưới đây là danh sách các hàm phản chiếu trong Python −
Chúng tôi đã sử dụng hàm này nhiều lần. Nó cho bạn biết đối tượng thuộc lớp nào.
Các câu lệnh sau in ra lớp tương ứng của các đối tượng kiểu dữ liệu tích hợp khác nhau.
print (type(10)) print (type(2.56)) print (type(2+3j)) print (type("Hello World")) print (type([1,2,3])) print (type({1:'one', 2:'two'}))
Ở đây, bạn sẽ nhận được output −
<class 'int'> <class 'float'> <class 'complex'> <class 'str'> <class 'list'> <class 'dict'>
Hãy xác minh loại của một đối tượng thuộc lớp do người dùng định nghĩa −
class test: pass obj = test() print (type(obj))
Nó sẽ tạo ra output −
<class '__main__.test'>
Đây là một hàm tích hợp sẵn khác trong Python, xác định xem một đối tượng có phải là một thể hiện của lớp đã cho hay không.
isinstance(obj, class)
Hàm này luôn trả về Boolean value , đúng nếu đối tượng thực sự thuộc về lớp đã cho và sai nếu không.
Các câu lệnh sau đây trả về True −
print (isinstance(10, int)) print (isinstance(2.56, float)) print (isinstance(2+3j, complex)) print (isinstance("Hello World", str))
Nó sẽ tạo ra output −
True True True True
Ngược lại, các câu lệnh này in ra False.
print (isinstance([1,2,3], tuple)) print (isinstance({1:'one', 2:'two'}, set))
Nó sẽ tạo ra output −
False False
Bạn cũng có thể thực hiện kiểm tra với một lớp do người dùng định nghĩa.
class test: pass obj = test() print (isinstance(obj, test))
Nó sẽ tạo ra output −
True
Trong Python, ngay cả các lớp cũng là đối tượng. Tất cả các lớp đều là đối tượng của lớp đối tượng. Điều này có thể được xác minh bằng đoạn mã sau −
class test: pass print (isinstance(int, object)) print (isinstance(str, object)) print (isinstance(test, object))
Tất cả các câu lệnh in ở trên đều in ra True.
Hàm này kiểm tra xem một lớp có phải là lớp con của một lớp khác hay không. Liên quan đến các lớp, không phải các thể hiện của chúng.
Như đã đề cập trước đó, tất cả các lớp Python đều được kế thừa từ lớp đối tượng. Do đó, kết quả của các câu lệnh in sau đây đều là True.
class test: pass print (issubclass(int, object)) print (issubclass(str, object)) print (issubclass(test, object))
Nó sẽ tạo ra output −
True True True
Một đối tượng được coi là có thể gọi nếu nó kích hoạt một quy trình nhất định. Một Python function , thực hiện một quy trình nhất định, là một đối tượng có thể gọi. Do đó, callable(function) trả về True. Bất kỳ hàm nào, được xây dựng sẵn, do người dùng định nghĩa, hoặc method đều có thể gọi. Các đối tượng của data types tích hợp sẵn như int, str, v.v., không phải là đối tượng có thể gọi.
def test(): pass print (callable("Hello")) print (callable(abs)) print (callable(list.clear([1,2]))) print (callable(test))
Một đối tượng string không thể được gọi. Nhưng abs là một hàm có thể được gọi. Phương thức pop của danh sách có thể được gọi, nhưng clear() thực sự là một lời gọi đến hàm và không phải là một đối tượng hàm, do đó không thể được gọi.
Nó sẽ tạo ra output −
False True True False True
Một thể hiện của lớp có thể được gọi nếu nó có phương thức __call__() . Trong ví dụ dưới đây, lớp kiểm tra bao gồm phương thức __call__() . Do đó, đối tượng của nó có thể được sử dụng như thể chúng ta đang gọi một hàm. Do đó, đối tượng của một lớp với hàm __call__() là một đối tượng có thể gọi.
class test: def __init__(self): pass def __call__(self): print ("Hello") obj = test() obj() print ("obj is callable?", callable(obj))
Nó sẽ tạo ra output −
Hello obj is callable? True
Hàm tích hợp getattr() lấy giá trị của thuộc tính được đặt tên của đối tượng.
class test: def __init__(self): self.name = "Manav" obj = test() print (getattr(obj, "name"))
Nó sẽ tạo ra output −
Manav
Hàm tích hợp setattr() thêm một thuộc tính mới vào đối tượng và gán cho nó một giá trị. Nó cũng có thể thay đổi giá trị của một thuộc tính đã tồn tại.
Trong ví dụ dưới đây, đối tượng của lớp kiểm tra có một thuộc tính duy nhất - name. Chúng tôi sử dụng setattr() để thêm thuộc tính age và để sửa đổi giá trị của thuộc tính name.
class test: def __init__(self): self.name = "Manav" obj = test() setattr(obj, "age", 20) setattr(obj, "name", "Madhav") print (obj.name, obj.age)
Nó sẽ tạo ra output −
Madhav 20
Hàm tích hợp sẵn này trả về True nếu thuộc tính được cho là có sẵn cho đối tượng đối số, và false nếu không. Chúng ta sử dụng cùng một lớp kiểm tra và kiểm tra xem nó có một thuộc tính nhất định hay không.
class test: def __init__(self): self.name = "Manav" obj = test() print (hasattr(obj, "age")) print (hasattr(obj, "name"))
Nó sẽ tạo ra output −
False True
Nếu hàm tích hợp này được gọi mà không có đối số, nó sẽ trả về các tên trong phạm vi hiện tại. Đối với bất kỳ đối tượng nào được sử dụng làm đối số, nó sẽ trả về một danh sách các thuộc tính của đối tượng đã cho và các thuộc tính có thể truy cập từ nó.
For a module object − hàm này trả về các thuộc tính của mô-đun.
For a class object − hàm này trả về các thuộc tính của nó, và đệ quy các thuộc tính của các lớp cơ sở của nó.
For any other object − các thuộc tính của nó, các thuộc tính của lớp của nó, và một cách đệ quy các thuộc tính của các lớp cơ sở của lớp đó.
print ("dir(int):", dir(int))
Nó sẽ tạo ra output −
dir(int): ['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__getstate__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_count', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
print ("dir(dict):", dir(dict))
Nó sẽ tạo ra output −
dir(dict): ['__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__ior__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__ror__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
class test: def __init__(self): self.name = "Manav" obj = test() print ("dir(obj):", dir(obj))
Nó sẽ tạo ra output −
dir(obj): ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']