0

As the title says, is there any function equivalent to the Perl's $AUTOLOAD ?

use strict; 
use warnings; 
use vars '$AUTOLOAD'; 


sample_function('7','11'); 


# AUTOLOAD() Function 
sub AUTOLOAD 
{ 
    print "AUTOLOAD is set to $AUTOLOAD\n"; 
    print "With arguments ", "@_\n"; 
} 

Output:

AUTOLOAD is set to main::sample_function
With arguments 7 11

Is there any such implementation in Python?

brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • 2
    For those who are wondering, Perl's `AUTOLOAD` is method called when a non-existent method is called on an class/object. For example, `$foo->bar` calls `$foo->AUTOLOAD` if the class specified by `$foo` or the class of the object specified by `$foo` doesn't have a method named `bar` and if it has a method named `AUTOLOAD`. – ikegami Jul 01 '20 at 20:40

1 Answers1

0

Well it really depends on what you want to achieve. For autoloading a missing package for example you can do something similar to this page

   import os.path 
   try:   
     import some_module 
   except ImportError:   
     import pip 
     pip.main(['install', '--user', 'some_module'])
     os.execv(__file__,sys.argv)

If you want to dynamically load something you can use the __init__.py file with something like the following code (I use this in some old script to load orator migration schema files). However you need to import * from <whatever_folder_has_this_init_file>:

import importlib
import inspect
import glob
from os.path import dirname, basename, isfile, join

def __get_defined_modules():
    modules_path = join(dirname(__file__), "migrations", "*.py")
    modules = glob.glob(modules_path)
    for f in modules:
        if isfile(f) and f.find('migration'):
            yield basename(f)[:-3]

def run_migrations(db):
    m = __get_defined_modules()
    for x in m:
        if x.find('migration') > -1:
            module_path='{}.migrations.{}'.format(basename(dirname(__file__)), x)
            for _, cls in inspect.getmembers(importlib.import_module(module_path), inspect.isclass):
                if cls.__module__ == module_path:
                    print("Loading and executing {}: {}".format(x, cls))
                    migration = cls()
                    migration.set_connection(db)
                    migration.up()

__all__ = list(__get_defined_modules()) + ['run_migrations']

Another way (which I don't really recommend) is using something along this lines (I did not test this):

import inspect, importlib def try_xx()
    try:
        some_xx()
    except NameError as e:
        func_name = e.split("'")[1]
        parts = func_name.split("_")
        for _, f in inspect.getmembers(importlib.import_module("/module/path/{}.py".format(parts[1])), inspect.isfunction):
            if f.__name__ == func_name:
                f()

But to answer to your question ... no, python does not have a builtin autoload mechanism because most of the times you anyway don't need it. You can read a great description of the why's here: Python modules autoloader? (it's about php that has also autoload, but you will get the point)

user1452962
  • 386
  • 3
  • 8
  • Thanks @user1452962. –  Jul 01 '20 at 20:28
  • The answer and the link is about automatically loading modules, but Perl's `AUTOLOAD` is method called when a non-existent method is called on an class/object. For example, `$foo->bar` calls `$foo->AUTOLOAD` if the class specified by `$foo` or the class of the object specified by `$foo` doesn't have a method named `bar` and if it has a method named `AUTOLOAD`. – ikegami Jul 01 '20 at 20:35