Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

And which mechanism is that exactly?


I edited the comment for clarity and there is no formal name that I can find, unfortunately.


I 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.


_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/

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/


Your first point is something I mentioned in my comment (although admittedly I mixed the order of the command). In general it's a bad idea to import everything from a module into the global namespace; it's recommended to keep it under some namespace for context:

I.e., assuming my_module has function foo, instead of:

  from my_module import *

  foo()
Use this:

  import my_module

  my_module.foo()
Or this:

  import my_module as mm

  mm.foo()


The one they clearly explained in the comment, using __get_attribute__


Yes, clearly explained in the update to the comment made after my question. :/




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: