2

I'm currently writing a library in python. I have a package called Selectors as a sub-directory of the library. I am trying to implement a new module in the package, but when I try to import it I get the error:

NameError: name '_RaceSelector__ResultSelector' is not defined

My directory looks like this:

Selectors
│ ├── __init__.py
│ ├── __init__.pyc
│ ├── __pycache__
│ │ ├── SeasonSelector.cpython-38.pyc
│ │ ├── Selector.cpython-38.pyc
│ │ ├── __init__.cpython-38.pyc
│ │ ├── race_selector.cpython-38.pyc
│ │ ├── result_selector.cpython-38.pyc
│ │ └── season_selector.cpython-38.pyc
│ ├── race_selector.py
│ ├── race_selector.pyc
│ ├── result_selector.py
│ ├── result_selector.pyc
│ ├── season_selector.py
│ ├── season_selector.pyc
│ ├── selector.py
│ └── selector.pyc

I want to use the modules in race_selector.py, here is that file:

from .selector import __Selector
from .result_selector import __ResultSelector
class RaceSelector(__Selector):
 data = []
 loaded_races = []
 header = []
 result_selector = __ResultSelector()

selector.py

import os
import csv
class __Selector:
 def __init__(self, file_name):
 self.data_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../data/' + file_name + '.csv')
 self.raw_data = self.load_data()
 self.data = self.get_data()

result_selector.py

import os
from .selector import __Selector
class __ResultSelector(__Selector):
 def __init__(self):
 super().__init__('results')

I am able to import selector just fine and works as intended, but result_selector produces the error.

Thanks

asked Dec 20, 2019 at 11:51
2
  • Are you sure that the error comes from result_selector.py? Because it mentions _RaceSelector, which I can't spot in your code. Commented Dec 20, 2019 at 11:58
  • Plus, is there any reason to not have the different selectors in one common file? Commented Dec 20, 2019 at 12:00

1 Answer 1

3

When you do the following:

result_selector = __ResultSelector()

Python searches for _RaceSelector__ResultSelector because there is 2 underscores.

As mentioned in PEP8:

If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python's name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name.
answered Dec 20, 2019 at 12:00
Sign up to request clarification or add additional context in comments.

2 Comments

Wow. Didn't know that.
Neither did I. Very useful to know. Thank you!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.