4 ms·
> Python has this (_ access). What exactly is being referenced here?
by scruple 3y ago
> Python has this (_ access).
What exactly is being referenced here?
- Supermancho 3y ago> I wish that my programming languages had a "public for testing only" scope. > Python has this (_ access) Bypassing CAMs is useful for testing. Python has a mechanism, which is used for that^...regardless of the intent of the feature. ^Underscores are a partially enforced convention for private methods. If your import stripped your access to an attribute, you can still access via __getattribute__() which reaches into the hierarchy. There are other tricks as well. You might call this a special method lookup.
- BerislavLopac 3y agoAnd which mechanism is that exactly?
- edgyquant 3y agoThe one they clearly explained in the comment, using __get_attribute__
- deleted 3y ago[deleted]
- BerislavLopac 3y agoYes, clearly explained in the update to the comment made after my question. :/
- deleted 3y ago[deleted]
- Supermancho 3y agoI edited the comment for clarity and there is no formal name that I can find, unfortunately.
- BerislavLopac 3y agoI still don't understand what you're talking about. > If your import stripped your access to an attribute Python doesn't have class access modifiers, and in particular import does not strip access to attributes in Python. There are two ways Python modifies behaviour in the presence of leading underscores: 1. If there is a module attribute (i.e. a variable in a module) starting with an underscore, it will not be imported when doing `import * from some_module` -- which is not recommended anyway. Importing `some_module` directly will give normal access to the attribute, as `some_module._foo`. 2. If a class or instance attribute's name begins with a double underscore, it will not be accessible directly; however its name is simply mungled at compile time: > class Foo: > __foobar = "__foobar" > > def __init__(self): > self.__bar = "__bar" > self.__baz__ = "__baz__" > > Foo.__foobar AttributeError: 'Foo' object has no attribute '__foobar' > foo = Foo() > foo.__bar AttributeError: 'Foo' object has no attribute '__bar' > Foo._Foo__foobar '__foobar' > foo._Foo__bar '__bar' > # Note that does not hold for attributes both starting and ending in double underscores > # (so-called 'dunder' attributes): foo.__baz__ '__baz__' You are correct that underscores are a convention, but in Python one simply cannot count on the kind of access control that exists in other languages, especially when writing code that is supposed to be executed in unknown contexts (i.e. a library). When writing tests, one presumably has full control over both the code and the execution context, so this kinds of tricks can be used relatively safely; that being said, test runners like pytest tend to provide their own abstractions and tools around those tricks anyway.
- Supermancho 3y ago_single_leading_underscore: weak “internal use” indicator. E.g. from M import * does not import objects whose names start with an underscore. - https://peps.python.org/pep-0008/ https://peps.python.org/pep-0008/ Ironically, there's a story on the frontpage of HN right now, regarding attribute handling in python, which may be of interest: https://lwn.net/SubscriberLink/943619/eaa8a4496fcba1fd/ https://lwn.net/SubscriberLink/943619/eaa8a4496fcba1fd/
- 3y ago