0

I'm creating a module that I'll import in a main script. In the module, called "colors", there's a function: "info()".

colors-module:

def info(function=None):
    print("\ncolors\n        Info\n")

The problem I have, is that I may also create a function called "info()", in the main script. This won't be a problem, as long as I import the colors-module as:

import colors

If so, I would call the function in the module by writing:

colors.info()

If I instead import the module as:

from colors import *

I have two functions called the exact same.

Main script:

from colors import *
def info():   # A
    print("Main script's function")

info()   # A
colors.info()   # Am I able to force use of the module name before calling the
                # function, if I import the module as in this script? Can this
                # be done from the module, and not from the main script? As said,
                # force use of module name, as "colors.info()", shall only apply
                # when the module is being imported with "from colors import *".

EDIT 1

The reason why I want to import the module this way, is because of global variables in it:

bwc0 = (0, 0, 0)
bwc1 = (1, 1, 1)
bwc2 = (2, 2, 2)
# All the way to 255

After a few answers, I'll try adding these to a class, and import that class as *, if possible. I also have a few functions in it, that I want imported as *, too. I'm not exactly sure how to import them, yet. It's probably easy, I suppose.

def redc(value):
    return value, 0, 0

def greenc(value):
    return 0, value, value

Thanks for all help

  • 1
    Using wildcards in imports is considered an anti-pattern – Vasili Syrakis Mar 06 '17 at 14:04
  • 1
    This would be a vary bad idea. I can only imagine all the question rolling in "Why am I unable to call function `info()` although I **explicitly** declared it in my script?". If somebody imports * ([which is bad](http://stackoverflow.com/questions/2386714/why-is-import-bad) anyway) and defines their own `info` function it would be absolutely horrible if this was ignored as a side-effect of another module being imported. – MB-F Mar 06 '17 at 14:04
  • I would do `import colors as co`, so you have both `info()` and `co.info()`: not much longer, and it saves headaches in the long run. – farsil Mar 06 '17 at 14:04
  • 1
    The functions you just import by their names, the `buc#` globals would be best as an array: `from colors import buc, redc, greenc, bluec` then you can do `buc[0]`, `buc[1]` all the way to `buc[255]` Also as an array you have less typing in the `colors` module: `buc = [(n,n,n) for n in range(256)]` – Duncan Mar 06 '17 at 14:28
  • I mainly want to import variables from the module, as *, only. If possible, I'll do so with a class, and two import statements: "import colors", and "from colors import class". See question edit for more. Thanks. – Andreas is moving to Codidact Mar 06 '17 at 14:30

3 Answers3

2

When importing * from the module you won't have two functions with the same name, you'll have one function with the name info. Which of the two (one in colors or one in main script) is used depends on where the definition of info in main is, relative to the from colors import * statement.

You can't "force" the module prefix in any way; if you didn't import colors with import colors you don't have that name bound to something you can refer to.

If typing long names is the thing you're trying to avoid, just rename the info function you bring in from colors by using the as clause of the from import statement:

from colors import info as c_info

This is one of the main reasons using star * imports are discouraged and why namespaces are such a good idea. With * you throw away the separate namespace (module colors) that holds the name info function and place it in the namespace for the main script thereby masking objects with the same name.

Dimitris Fasarakis Hilliard
  • 150,925
  • 31
  • 268
  • 253
2

No, you can't force how your function is called. If someone is writing code to call your function it's up to them to ensure that they are actually able to call it.

Either:

import colors

Or:

from colors import info as colors_info

will work if they want to call it. Otherwise they just have to avoid creating a function with a conflicting name.

BTW, as a general case don't use from colors import * as it means you don't know what function's you're importing. For example:

from colors import *
from foobar import *

now, is info() coming from colors or foobar? You can't be sure, and somewhere down the line the answer may change. So always import the names you need explicitly and that way at least they're listed in the module that uses them so you can see when conflicts will arise.

Duncan
  • 92,073
  • 11
  • 122
  • 156
  • In PyCharm, which I use, I'm always notified about where a function comes from. I'm also updating my question, to tell why I want to use "from colors import *". Thanks for an answer. – Andreas is moving to Codidact Mar 06 '17 at 14:13
  • 1
    @Andreas, no PyCharm will tell you where `info()` comes from while you are writing the code. But it won't tell you if the imports change when someone edits `foobar` and you don't go near your original module again. That's why it's a danger, not when you're writing the code but when things change much later after you think this code is done and dusted. – Duncan Mar 06 '17 at 14:21
0

You can make the colors like a class. And the function of info is method of colors class

so, you just instant of colors and call the info() method

xiangjian Wu
  • 116
  • 1
  • 1
  • 8