init method shorthand¶
basedpython lets a class declare its constructor with the bare keyword init
instead of def __init__. parameters prefixed with let are auto-assigned to
self.<name> at the top of the method body, so the constructor and the
instance-attribute declarations share a single signature
transpiles to:
scope¶
init(...) is only recognised inside a class body. at module scope
init(...) is still an ordinary function call expression. the parser tracks
class nesting so the keyword does not leak into module-level call sites
bodyless and body forms¶
both shapes are accepted:
a bodyless init(...) is filled in with : ... when no let parameter
produces a body line. body-bearing init(...) keeps the user's statements;
let self-assignments are prepended ahead of them
defaults¶
a parameter default is lowered exactly as it is on a def. a default that is
constructed rather than a constant is re-evaluated per call rather than shared
between every instance, and a required parameter may follow a defaulted one:
class Fight:
def __init__(self, seen: set[int] = _MISSING, last: int = _MISSING):
if seen is _MISSING:
seen = set()
if last is _MISSING:
raise TypeError("__init__() missing required argument: 'last'")
self.seen: set[int] = seen
self.last: int = last
let parameter modifier¶
let may appear on any positional, positional-only, keyword-only, *args,
or **kwargs parameter inside init. each let parameter emits a
self-assignment using the parameter's annotation (self.<name>: <ann> = <name>)
or, if unannotated, a bare assignment (self.<name> = <name>)
a non-let parameter is just a parameter — no attribute is created for it
the attribute is read-only, exactly as a class-body let a: int is: the
constructor binds it and nothing else may write it
that is what lets a class be covariant in a type parameter it only stores — a widened view cannot corrupt an attribute nothing can write to:
var and visibility modifiers¶
var is the mutable counterpart of let; on an init parameter it
self-assigns identically, but the attribute stays writable — and a class that
stores one is invariant in its type. a visibility modifier — private or public — may
precede let / var. private name-mangles the synthesised attribute to
self.__name, while the parameter itself keeps its declared name:
transpiles to:
a visibility modifier without let / var has no attribute to name, and any
other modifier keyword (final, abstract, …) is meaningless in this
position — both are reported as errors
modifiers¶
a modifier chain in front of init applies to the constructor exactly as it
would to the def __init__ it stands for:
static and the class def classmethod modifier say which kind of function a
def is, and a constructor is neither, so they are rejected
private constructors¶
private init means the class decides how its instances are made: its own body
may construct it, and nothing else may. that is what a factory method rests on
class Id:
private init(let raw: str)
@classmethod
def parse(cls, text: str) -> Id:
return Id(text.strip())
Id("x") # rejected
a subclass is outside the base's body like any other caller, so it may neither
construct the base nor — while it inherits the private constructor — be
constructed itself. declaring an init of its own makes it constructible again
the guarantee is over the class's own name. a type[Id] may hold a subclass,
and a subclass is free to declare a constructor of its own, so calling one is not
refused
unlike an ordinary private method, the emitted __init__ is not renamed:
python calls a constructor by its exact name, so there is no spelling that would
hide it and leave the class constructible. a private constructor is a static
guarantee rather than a runtime one
implicit self¶
self may be omitted from the parameter list. it is implied, so it is
injected into the generated def __init__ signature and let / var
attributes and self references in the body resolve against it:
transpiles to:
why¶
constructors with self.x = x; self.y = y boilerplate are ubiquitous.
collapsing the parameter list and the attribute declarations into one line
removes that duplication without depending on @dataclass semantics