Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A f**king problem with sys.path #323

Open
R4v3nl0 opened this issue Dec 14, 2023 · 0 comments
Open

A f**king problem with sys.path #323

R4v3nl0 opened this issue Dec 14, 2023 · 0 comments

Comments

@R4v3nl0
Copy link

R4v3nl0 commented Dec 14, 2023

Problem

If you import some file or object with different path, it will have different id..
Look like this

The directory tree:

.
├── hole
│   ├── __init__.py
│   ├── base.py
│   └── caller.py
└── main.py

hole/init.py

import sys
from pathlib import Path

# allow imported as third-party package
__PATH = str(Path(__file__).parent)
if __PATH not in sys.path:
    sys.path.append(__PATH)

hole/base.py

class Base:
    shared = []

    @staticmethod
    def add(x):
        Base.shared.append(x)

hole/caller.py

from base import Base

def caller():
    Base.add(1)
    print(Base.shared)

main.py

from hole import caller
from hole.base import Base

caller.caller()
print(Base.shared)

After run command python3 main.py, u will get the output:

[1]
[]

Why????

Because sys.path causes them to have different modules, different objects are used.

We can clearly observe this distinction with Base.__dict__

Add print(Base.__dict__) after print(Base.shared) in main.py and hole/caller.py

The output:

[1]
{'__module__': 'base', 'shared': [1], 'add': <staticmethod(<function Base.add at 0x1007fd900>)>, '__dict__': <attribute '__dict__' of 'Base' objects>, '__weakref__': <attribute '__weakref__' of 'Base' objects>, '__doc__': None}
[]
{'__module__': 'hole.base', 'shared': [], 'add': <staticmethod(<function Base.add at 0x1007fda20>)>, '__dict__': <attribute '__dict__' of 'Base' objects>, '__weakref__': <attribute '__weakref__' of 'Base' objects>, '__doc__': None}

Okay, We can see that the call in hole/caller.py outputs '__module__': 'base' and the call in main.py outputs '__module__': 'hole.base'

How to fix it?

If we need to use the class attribute in different files and want they use the same object, you may have these two options

Attention: If there is no interference from sys.path, you don't need to care

Option 1

Add a function to return the Base class in a python file which in hole directory and uses from base import Base

Like add get_base in hole/caller.py

from base import Base

def caller():
    Base.add(1)
    print(Base.shared)
    print(Base.__dict__)


def get_base():
    return Base

And when you want to use the class attribute in Base, first call get_base to get the base object which __module__ is base, and then call base.xxx

Option 2

Import Base like you did in caller.py

Attention: Pylance will report missing imports, lmao

main.py

from hole import caller
from base import Base

caller.caller()
print(Base.shared)
print(Base.__dict__)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant