#๐Ÿ”’ weird idea

112 messages ยท Page 1 of 1 (latest)

pure cedar
#

Say I have a folder called commands and inside it are files lets say jump.py, move.py, slide.py and inside each of those files are functions that match the file names minus the extension of course. how would I go about dynamically importing all those functions ?
Say I want to use them like so

for cmd in commands_list:
    add_command(cmd)
dry fieldBOT
#

@pure cedar

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

lunar musk
#
import jump
import move
import slide

commands_list = [jump.jump, move.move, slide.slide]

for cmd in commands_list:
    add_command(cmd)
pure cedar
#

I don't want it hardcoded

lunar musk
#

Oh I see

pure cedar
#

I want it to work dynamically

lunar musk
#

You'll need to get the names of the files and do something with importlib

#

!d importlib.import_module

dry fieldBOT
#

importlib.import_module(name, package=None)```
Import a module. The *name* argument specifies what module to import in absolute or relative terms (e.g. either `pkg.mod` or `..mod`). If the name is specified in relative terms, then the *package* argument must be set to the name of the package which is to act as the anchor for resolving the package name (e.g. `import_module('..mod', 'pkg.subpkg')` will import `pkg.mod`).

The [`import_module()`](https://docs.python.org/3/library/importlib.html#importlib.import_module) function acts as a simplifying wrapper around [`importlib.__import__()`](https://docs.python.org/3/library/importlib.html#importlib.__import__). This means all semantics of the function are derived from [`importlib.__import__()`](https://docs.python.org/3/library/importlib.html#importlib.__import__). The most important difference between these two functions is that [`import_module()`](https://docs.python.org/3/library/importlib.html#importlib.import_module) returns the specified package or module (e.g. `pkg.mod`), while [`__import__()`](https://docs.python.org/3/library/functions.html#import__) returns the top\-level package or module (e.g. `pkg`).
lunar musk
#

Is this to save time?

pure cedar
#

well I'll have a shit load of cmds

lunar musk
#

Because I highly highly recommend not doing this unless it's just for fun

pure cedar
#

I don't feel like importing them manually

#

lol

wary wraith
#

Manually is easier

lunar musk
#

You could just write a script that gets all the names of the files, edits them into what you want, and puts them into a file

pure cedar
#

except maybe run time

pure cedar
#

which is obv wrong

#

since command would be the module

#

not the function

lunar musk
#

Just make a script that does the "manual way" for you

#

If you have 100s of commands

pure cedar
#

but still that'd look hella ugly

#

imagine 100 import x then another 100 x.x

lunar musk
#

That's what collapsible sections are for in IDEs

pure cedar
#

๐Ÿ˜ญ

lunar musk
#

Or just stuff it in another file and import the list from there

pure cedar
#

I really wanna do it dynamically ngl

#

to learn and also

#

yk

#

kewl

lunar musk
#

Yeah I know what you mean

pure cedar
#

xd

#

maybe something like..... hm

#

oh wait

#

if they're in the same directory as the main file thats ran

#

wouldn't they be part of the __globals__ ?

lunar musk
#

I don't believe so

pure cedar
#

hm

lunar musk
#

Your importlib code is almost functional

pure cedar
#

almost is the keyword here

lunar musk
#

Just switch the first argument to an absolute import and get rid of the second one

#

Then use the name of the file and exec it I think

pure cedar
#
for file in listdir("commands"):
  module = import_module(file)
  command = module.__locals__[file[:-3]]

  add_command(command)
#

would that work?

lunar musk
#

Well you're missing a ]

pure cedar
#

ha

lunar musk
#

But maybe?

pure cedar
#

lets try it

#

whats the diff between globals and locals again?

#

๐Ÿ˜ญ

lunar musk
#

So you'll want globals

#

I think

#

Gonna be honest I've never done this before

pure cedar
#

I have done some weird shit with globals and locals b4

#

nothing with imports tho

#

first time for me b4

#

but its fun

#

it didnt work btw

lunar musk
#

Dang

#

Wait isn't locals a method

pure cedar
#
ModuleNotFoundError: No module named 'account'
pure cedar
#

same as str iter etc...

#

vars

lunar musk
#

Try doing package.(filename)

#

What ever your package is

pure cedar
#

I tried

#
ModuleNotFoundError: No module named 'commands.account.py'; 'commands.account' is not a package
lunar musk
#

You have the .py

opal zealot
pure cedar
#
module = __import__(
                name=f"commands.{file[:-3]}",
                fromlist=(file[:-3])
            )

            command = module.__locals__[file:-3]
#
AttributeError: module 'commands.account' has no attribute '__locals__'
#

hmmmmmmm

lunar musk
#

Try __globals__

pure cedar
#

its ModuleType

#

I guess it dont have that

lunar musk
#

Hmm

opal zealot
#

no

#

sys.modules

#

__pycache__ has to do with bytecode compilation

pure cedar
#

hm

lunar musk
#

Does it have __dict__?

#

Or __all__?

opal zealot
#

yes modules have a __dict__

pure cedar
# lunar musk Does it have `__dict__`?
__all__ = ["load_module"]


from string import ascii_uppercase, ascii_lowercase, digits
from secrets import choice
from importlib.util import spec_from_file_location, module_from_spec
from sys import modules


def gensym(length=32, prefix="gensym_") -> str:
    alphabet = ascii_uppercase + ascii_lowercase + digits
    symbol = "".join([choice(alphabet) for i in range(length)])

    return prefix + symbol


async def load_module(source, module_name=None):
    if module_name == None:
        module_name = gensym()

    spec = spec_from_file_location(module_name, source)
    module = module_from_spec(spec)
    modules[module_name] = module
    spec.loader.exec_module(module)

    return module
#

not my code but this should work apparently

#

-# spoiler alert...its not

#
        for file in listdir("commands"):
            if file.startswith("__"):
                continue

            module = await load_module(f"commands.{file[:-3]}")

            command = module.__dict__[file:-3]
            
            print(command)

            self.tree.add_command(command)
#
AttributeError: 'NoneType' object has no attribute 'loader'
#

so spec is none ig

#

mhmhmhmhmmhhmhm

#
module = await load_module(f"commands/{file}")
#

aha ic

#

__dict__ is not hashable ig?

#

aha

#
        for file in listdir("commands"):
            if file.startswith("__"):
                continue

            module = await load_module(f"commands/{file}")

            command = module.__dict__.get(file[:-3])

            self.tree.add_command(command)
#

works!

#

I think

#

it ran

#

idk if the cmd is working

#

lemme test it

#

ayyyyyyy

#

it works

#

my genuis has increased by 0.024!

#

!close

dry fieldBOT
#
Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.