[{"data":1,"prerenderedAt":63},["ShallowReactive",2],{"qa-\u002Fpython\u002Fidioms\u002Feafp-lbyl":3},{"page":4,"siblings":54,"blog":45},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":45,"seo":46,"seoDescription":47,"stem":48,"subtopic":49,"topic":50,"topicSlug":51,"updated":52,"__hash__":53},"qa\u002Fpython\u002Fidioms\u002Feafp-lbyl.md","Eafp Lbyl",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","Python","python",{},true,1,"\u002Fpython\u002Fidioms\u002Feafp-lbyl",[23,28,32,37,41],{"id":24,"difficulty":25,"q":26,"a":27},"eafp-lbyl-meaning","easy","What do EAFP and LBYL mean?","**EAFP** = \"**Easier to Ask Forgiveness than Permission**\": just **attempt**\nthe operation and handle the exception if it fails. **LBYL** = \"**Look Before\nYou Leap**\": **check** the preconditions first, then act only if the checks\npass. They are two styles for handling things that *might* go wrong.\n\n```python\n# LBYL — check first\nif \"key\" in config:\n    value = config[\"key\"]\n\n# EAFP — try and handle failure\ntry:\n    value = config[\"key\"]\nexcept KeyError:\n    value = default\n```\n\nEAFP is the **Pythonic** default — it reads naturally and avoids redundant\nchecks. Rule of thumb: in Python, **try the operation and catch the specific\nexception** rather than pre-validating every condition.\n",{"id":29,"difficulty":14,"q":30,"a":31},"why-eafp-preferred","Why is EAFP preferred in Python?","EAFP fits Python's design: exceptions are **cheap** and **idiomatic**, and the\nstyle avoids **duplicating logic**. With LBYL you often check a condition and\nthen perform the same lookup\u002Foperation again, doing the work twice. EAFP also\nstays correct when an object merely **behaves like** the expected type\n(duck typing) rather than passing an explicit type check.\n\n```python\n# LBYL duplicates the access and breaks on duck-typed objects\nif hasattr(obj, \"read\") and callable(obj.read):\n    data = obj.read()\n\n# EAFP — just use it; let the exception surface real problems\ntry:\n    data = obj.read()\nexcept AttributeError:\n    data = None\n```\n\nThe happy path stays uncluttered and the error handling is explicit. Rule of\nthumb: write the **common case** as straight-line code and catch the\n**specific** exception for the rare failure.\n",{"id":33,"difficulty":34,"q":35,"a":36},"lbyl-race-condition","hard","What race condition does LBYL invite?","LBYL introduces a **TOCTOU** bug — \"**Time Of Check to Time Of Use**\". Between\nthe moment you **check** a condition and the moment you **act** on it, another\nthread or process can change the state, so the check is **stale** and the\naction fails or corrupts data. EAFP avoids the gap by acting atomically and\nhandling failure.\n\n```python\nimport os\n# LBYL — file can be deleted between the check and the open (race!)\nif os.path.exists(path):\n    with open(path) as f:    # may still raise FileNotFoundError\n        data = f.read()\n\n# EAFP — no window; the open either works or raises\ntry:\n    with open(path) as f:\n        data = f.read()\nexcept FileNotFoundError:\n    data = None\n```\n\nThe check-then-act pattern is unsafe in concurrent or filesystem contexts.\nRule of thumb: for files, sockets, and shared state, **attempt the operation**\nand handle the exception rather than checking first.\n",{"id":38,"difficulty":14,"q":39,"a":40},"dict-get-vs-check","When should you use dict.get versus checking for a key?","`dict.get(key, default)` returns the value if present and the **default**\n(`None` if unspecified) otherwise — a clean one-liner that avoids both the\n`if key in d` check **and** a `try\u002Fexcept KeyError`. Use a membership check or\n`try\u002Fexcept` only when you must **distinguish a missing key from a stored\n`None`**, or run different logic in each branch.\n\n```python\ncounts = {\"a\": 1}\ncounts.get(\"b\")          # None — no KeyError\ncounts.get(\"b\", 0)       # 0    — supply a default\n\n# need to tell \"missing\" from \"stored None\"? then check explicitly\nif \"b\" in counts:\n    ...\n# or accumulate with setdefault \u002F defaultdict\ncounts.setdefault(\"c\", 0)\n```\n\nFor counting\u002Fgrouping, `collections.defaultdict` or `Counter` is even cleaner.\nRule of thumb: reach for `.get()` with a default for \"value or fallback\", and\nonly branch explicitly when missing-ness itself is meaningful.\n",{"id":42,"difficulty":34,"q":43,"a":44},"eafp-pitfalls","What are the pitfalls of EAFP, and how do you avoid them?","EAFP done carelessly causes two problems. First, a **too-broad `except`**\n(bare `except:` or `except Exception`) can **swallow unrelated bugs** —\ncatching a `KeyError` you didn't intend, or hiding a `NameError`. Second, the\n`try` block should wrap **only** the line that can fail, so you don't\naccidentally catch exceptions from surrounding code.\n\n```python\n# Bad — hides real errors and over-wide try block\ntry:\n    value = config[\"key\"]\n    result = expensive_call(value)   # its errors get caught too!\nexcept Exception:\n    value = default\n\n# Good — narrow exception, minimal try body\ntry:\n    value = config[\"key\"]\nexcept KeyError:\n    value = default\nresult = expensive_call(value)       # outside the try\n```\n\nAlways catch the **most specific** exception and keep the `try` body small.\nRule of thumb: EAFP means \"catch the *one* expected failure\", never \"catch\neverything and hope\".\n",null,{"description":11},"Python interview questions on EAFP vs LBYL, why try\u002Fexcept is preferred, the race conditions LBYL invites, and dict.get versus checking for a key.","python\u002Fidioms\u002Feafp-lbyl","EAFP vs LBYL","Pythonic Idioms","idioms","2026-06-18","bCZ-XKDsdon8EdwPgbyY1qZW_3AfSyoMZOhOsdPFSIw",[55,56,59],{"subtopic":49,"path":21,"order":20},{"subtopic":57,"path":58,"order":12},"PEP 8 & Style","\u002Fpython\u002Fidioms\u002Fpep8-style",{"subtopic":60,"path":61,"order":62},"Common Gotchas & Anti-patterns","\u002Fpython\u002Fidioms\u002Fgotchas",3,1781808682363]