1. ホーム
  2. スクリプト・コラム
  3. パイソン

PythonにおけるReflectionの概要

2022-01-27 01:11:12

アプリケーションの実行時の状態、プロパティ、メソッドを文字列でマッピングしたり変更したりするには、次の4つの方法のいずれかを使用します。

''' 
   Use the getattr(object, name_str, default=None) method to get the memory address of the corresponding method or attribute in the object
   method or attribute
   If it's an attribute: return the attribute value directly
   If it is a method: return the memory address of the method     
   '''

# hasattr(object,name_str) Determines if the object has a method or attribute named name_str

コードデモです。

# -*- coding:utf8 -*-
class Person(object):
    def __init__(self, name):
        self.name = name

    def fun(self):
        print("%s is playing" % self.name)

p1 = Person("someone flying")

name_str = input("Please enter a method or attribute").strip()
# hasattr(object,name_str) Determine if the object has a method or attribute named name_str
if hasattr(p1, name_str):
   ''' 
   If it does, you can use the getattr(object, name_str, default=None) method to get the memory of the corresponding method or attribute in the object.
   The memory address of the corresponding method or attribute
   If it is an attribute: return the value of the attribute directly
   If it is a method: return the memory address of the method     
   '''
   print(getattr(p1, name_str , 80))
   # >>>name: someone who flies
   # >>>fun : <bound method Person.fun of <__main__.Person object at 0x0000020B76A81370>>
   # So if it's a method, then it can be handled like this
   a = getattr(p1, name_str)
   a()
else:
    print("The object does not have these attributes and methods")

Demonstration of determining and getting

オブジェクトがキーボード入力からこのメソッドを持っていない場合、setattr を使ってメソッドを追加することができます。

def bulk(self):
    print("This is a method created outside the class of %s object"%self.name)


class Person(object):
    def __init__(self, name):
        self.name = name

    def fun1(self):
        print("%s is playing" % self.name)

p1 = Person("someone flying")
name_str = input("Please enter your method or attribute").strip()
if hasattr(p1, name_str):
    a = getattr(p1, name_str)
    a()
else: # If there is no such method, then create an already existing one for it
    """
    setattr(p1, name_str, bulk)
    Add a method to the object p1 that already exists for bulk, named name_str
    """
    setattr(p1, name_str, bulk)
    a = getattr(p1, name_str)
    a(p1)
"""
Run the results
Please enter your method or attribute ui
This is a method created outside the class of someone's fly object
"""

setattr(p1, name_str, bulk) add method

オブジェクトにキーボードから入力できるメソッドがない場合は、setattrを使用して属性を追加します。

class Person(object):
    def __init__(self, name):
        self.name = name

p1 = Person("Someone who flies")
name_str = input("Please enter your method or attribute").strip()
if hasattr(p1, name_str):
    a = getattr(p1, name_str)
    print(a)
    # You can also fix the value of an existing attribute with setattr
    setattr(p1, name_str, "fly")
    print(p1.name)
else: # If there is no such attribute, then add an attribute for it and set a default value of 20 for it
    setattr(p1, name_str, 20)
    a = getattr(p1, name_str)
    print(a)
"""
Run the result.
Please enter your method or attribute name
Someone flies
fly

Run result.
Please enter your method or attribute age
20
"""

setattr(p1, name_str, index) adds the attribute

オブジェクトから属性やメソッドを削除する ( メソッドが削除されない場合 )

class Person(object):
    def __init__(self, name):
        self.name = name

    def fun(self):
        print("This is an instance method")

p1 = Person("Someone who flies")
name_str = input("Please enter your method or attribute").strip()
if hasattr(p1, name_str):
    # Delete the attribute or method of this object
    delattr(p1, name_str)
else:
    pass

print(p1.name)
p1.fun()
"""
Run the result.
Please enter the name of your method or attribute
AttributeError: 'Person' object has no attribute 'name'

Runtime result.
Please enter your method or attribute fun
AttributeError: fun
"""

delattr(p1, name_str) only removes attributes, and dynamically added methods

注:setattrで動的に追加されたメソッドをdelattrで削除できるのも錯覚です。本当は、setattr によって追加されたメソッドは、オブジェクトにメソッドを追加しているのではなく、属性を追加しているのです。setattrメソッドの第2パラメータは属性の名前、そして属性の値は外部関数への参照アドレスなので、このオブジェクトの属性を呼び出すと、実際には間接的に関数を呼び出していることになります。 つまり、このオブジェクトの属性を呼び出すと、実際には間接的に関数を呼び出しているので、オブジェクトにメソッドが追加されたように見えますが、本質的にはやはり属性を追加していることになるのです。 setattrもdelattrも、実はオブジェクトのプロパティに対してのみ操作が可能で、オブジェクトのメソッドに対して直接操作することはできません。

Pythonのリフレクションについてのこの記事はこれで終わりです。Pythonでのリフレクションについてのより詳しい情報は、Scripting Houseの過去の記事を検索するか、以下の関連記事を引き続き参照してください。