getattr() 및 setattr() 함수 사용하기
Python 은 객체 속성에 동적으로 접근하고 수정할 수 있는 내장 함수를 제공합니다. 이러한 함수는 런타임까지 알 수 없는 속성 이름으로 작업하려는 경우 특히 유용합니다.
getattr() 함수
getattr() 함수를 사용하면 속성 이름을 문자열로 사용하여 속성에 접근할 수 있습니다. 구문은 다음과 같습니다.
getattr(object, attribute_name, default_value)
object: 속성에 접근하려는 객체
attribute_name: 속성 이름을 포함하는 문자열
default_value: 속성이 존재하지 않는 경우 반환할 선택적 값
/home/labex/project 디렉토리에 dynamic_attributes.py라는 새 파일을 생성해 보겠습니다.
class Person:
def __init__(self, name, age, job):
self.name = name
self.age = age
self.job = job
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create a Person object
john = Person("John", 30, "Developer")
## List of attributes to access
attributes = ["name", "age", "job", "address"]
## Access attributes using getattr()
print("Accessing attributes using getattr():")
for attr in attributes:
## The third parameter is the default value if the attribute doesn't exist
value = getattr(john, attr, "Not available")
print(f"{attr.capitalize()}: {value}")
## Call a method using getattr
greet_method = getattr(john, "greet")
greeting = greet_method()
print(f"Greeting: {greeting}")
이 코드를 실행합니다.
python3 /home/labex/project/dynamic_attributes.py
다음과 같은 출력을 볼 수 있습니다.
Accessing attributes using getattr():
Name: John
Age: 30
Job: Developer
Address: Not available
Greeting: Hello, my name is John and I am 30 years old.
존재하지 않는 address 속성의 경우, getattr()은 오류를 발생시키는 대신 기본값 "Not available"을 반환합니다.
setattr() 함수
setattr() 함수를 사용하면 속성 이름을 문자열로 사용하여 속성을 설정할 수 있습니다. 구문은 다음과 같습니다.
setattr(object, attribute_name, value)
object: 속성을 설정하려는 객체
attribute_name: 속성 이름을 포함하는 문자열
value: 속성에 할당할 값
setattr() 사용 예제를 포함하도록 dynamic_attributes.py 파일을 수정해 보겠습니다.
class Person:
def __init__(self, name, age, job):
self.name = name
self.age = age
self.job = job
def greet(self):
return f"Hello, my name is {self.name} and I am {self.age} years old."
## Create a Person object
john = Person("John", 30, "Developer")
print("Original attributes:")
print(f"Name: {john.name}")
print(f"Age: {john.age}")
print(f"Job: {john.job}")
## Modify attributes using setattr()
print("\nModifying attributes using setattr():")
setattr(john, "name", "John Smith")
setattr(john, "age", 31)
setattr(john, "job", "Senior Developer")
## Add a new attribute using setattr()
setattr(john, "address", "123 Main St")
## Print the modified attributes
print("\nModified attributes:")
print(f"Name: {john.name}")
print(f"Age: {john.age}")
print(f"Job: {john.job}")
print(f"Address: {john.address}")
## Access attributes using getattr()
print("\nAccessing attributes using getattr():")
for attr in ["name", "age", "job", "address"]:
value = getattr(john, attr, "Not available")
print(f"{attr.capitalize()}: {value}")
업데이트된 코드를 실행합니다.
python3 /home/labex/project/dynamic_attributes.py
다음과 같은 출력을 볼 수 있습니다.
Original attributes:
Name: John
Age: 30
Job: Developer
Modifying attributes using setattr():
Modified attributes:
Name: John Smith
Age: 31
Job: Senior Developer
Address: 123 Main St
Accessing attributes using getattr():
Name: John Smith
Age: 31
Job: Senior Developer
Address: 123 Main St
기존 속성을 수정하고 클래스에 정의되지 않은 완전히 새로운 속성 (address) 을 추가할 수 있었습니다.
실용적인 예시
동적 속성 접근 및 수정이 유용한 더 실용적인 예시를 만들어 보겠습니다. /home/labex/project 디렉토리에 data_processor.py라는 파일을 생성합니다.
class DataRecord:
def __init__(self):
## Start with no attributes
pass
## Create a function to process a dictionary into an object
def dict_to_object(data_dict):
record = DataRecord()
for key, value in data_dict.items():
setattr(record, key, value)
return record
## Sample data (could come from a database, API, etc.)
user_data = {
"user_id": 12345,
"username": "johndoe",
"email": "john@example.com",
"active": True,
"login_count": 27
}
## Convert the dictionary to an object
user = dict_to_object(user_data)
## Access the attributes
print(f"User ID: {user.user_id}")
print(f"Username: {user.username}")
print(f"Email: {user.email}")
print(f"Active: {user.active}")
print(f"Login Count: {user.login_count}")
## We can also add or modify attributes
setattr(user, "last_login", "2023-09-15")
setattr(user, "login_count", 28)
print("\nAfter modifications:")
print(f"Login Count: {user.login_count}")
print(f"Last Login: {user.last_login}")
## We can also access all attributes dynamically
print("\nAll attributes:")
for attr in ["user_id", "username", "email", "active", "login_count", "last_login"]:
value = getattr(user, attr, None)
print(f"{attr}: {value}")
이 코드를 실행합니다.
python3 /home/labex/project/data_processor.py
다음과 같은 출력을 볼 수 있습니다.
User ID: 12345
Username: johndoe
Email: john@example.com
Active: True
Login Count: 27
After modifications:
Login Count: 28
Last Login: 2023-09-15
All attributes:
user_id: 12345
username: johndoe
email: john@example.com
active: True
login_count: 28
last_login: 2023-09-15
이 예제는 데이터베이스, API 또는 파일에서 가져올 수 있는 딕셔너리에서 데이터를 객체로 변환한 다음 해당 속성에 동적으로 접근하거나 수정하는 방법을 보여줍니다.