Courseiva
Object-Oriented ProgrammingeasyMultiple ChoiceObjective-mapped

Logging Attribute Access via __getattribute__

A developer wants to create a class that logs every attribute access on an instance. Which special method should they override?

Quick Answer

The answer is `__getattribute__`, because this special method is called unconditionally for every attribute access on an instance, making it the correct choice for logging all attribute accesses. Overriding `__getattribute__` allows you to intercept and log each access before the attribute is retrieved, whereas `__getattr__` is only invoked when the attribute is not found via normal lookup. On the Certified Associate Python Programmer PCAP exam, this distinction tests your understanding of Python’s attribute access protocol and object model, often appearing in questions about debugging, auditing, or metaprogramming. A common trap is confusing `__getattribute__` with `__getattr__`—remember that `__getattr__` is a fallback for missing attributes only. For a memory tip, think of `__getattribute__` as the “always-on” gatekeeper for every dot access, while `__getattr__` is the “last resort” rescue handler.

⚠ Common exam trap

A common mix-up: candidates confuse `__getattr__` (called only on missing attributes) with `__getattribute__` (called on every access), and Python Institute often tests this distinction by presenting a scenario requiring unconditional interception.

Answer choices

Why each option matters

Answer the question above first, then reveal the full breakdown to understand why each option is right or wrong.

Correct answer & explanation

`__getattribute__`

`__getattribute__` is the special method that is called unconditionally for every attribute access on an instance, making it the appropriate choice for logging all attribute accesses. Overriding this method allows the developer to intercept and log each access before the attribute is retrieved, whereas `__getattr__` is only invoked when the attribute is not found via normal lookup.

Answer analysis

Option-by-option breakdown

For each option: why learners choose it and why it is or isn't the right answer here.

  • `__getattr__`

    Why it's wrong here

    `__getattr__` is only called when the attribute is not found via normal lookup, not for every access.

  • `__getattribute__`

    Why this is correct

    This method is invoked for every attribute access, making it suitable for logging.

  • `__setattr__`

    Why it's wrong here

    `__setattr__` is called for attribute assignment, not access.

  • `__delattr__`

    Why it's wrong here

    `__delattr__` is called for attribute deletion, not access.

About these practice questions

This PCAP question is part of Courseiva's 169-question bank — original exam-style content with full explanations and wrong-answer analysis, never real exam questions or exam dumps. Learn why practice questions differ from exam dumps →

How Courseiva writes practice questions · Editorial policy

Same concept, more angles

1 more way this is tested on PCAP

These questions test the same concept from different angles. Work through them to make sure you can recognise it however the exam phrases it.

Variation 1. A developer wants a class 'LoggedDict' that behaves like a dict but logs all attribute access in the console. Which method override correctly implements this for getting an attribute?

hard
  • A.def __get__(self, instance, owner): print(f'Access'); return self
  • B.def __getattribute__(self, name): print(f'Access {name}'); return super().__getattribute__(name)
  • C.def __getattr__(self, name): print(f'Access {name}'); return self.__dict__[name]
  • D.def __getitem__(self, key): print(f'Access {key}'); return dict.__getitem__(self, key)

Why B: `__getattribute__` is the universal method called for every attribute access on an object. By overriding it, the developer can log the attribute name before delegating to the superclass implementation via `super().__getattribute__(name)`, which preserves the normal attribute lookup chain. This ensures that all attribute accesses (including those that exist and those that don't) are logged, which is the requirement for 'LoggedDict'.

JA

Written by Johnson Ajibi, MSc IT Security

Senior Network & Security Engineer · founder of Courseiva

This PCAP practice question is part of Courseiva's free Python Institute certification practice question bank. Courseiva provides original exam-style practice questions with explanations, topic-based practice, mock exams, readiness tracking, and study analytics to help learners prepare for the PCAP exam.