Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Use an import done inside of a class in a function

Can anyone explain how to make the following example work? Since several functions inside of the class will use the same function from platform I thought it would be better to import it right inside of the class, but I don't see how I can use it inside of the function (since I constantly get errors about it).

#!/usr/bin/python

class test:
   from platform import system
   is_linux(self):
      system = system()
      if system == "Linux": return True

A better example:

#!/usr/bin/python

# Add ANSI colour strings
class stdout:
    from sys import stdout
    def message(message, self):  stdout.write(message)

Note: This is just a snippet, there are some parts missing but an example of what I mean.
I know I could probably just move system = system() and use self.system but perhaps a better way?

like image 908
Jordon Bedwell Avatar asked Jul 30 '11 13:07

Jordon Bedwell


2 Answers

Well, it is not that simple. Actually, import statement in many aspects looks like direct definition of something in place of it. If you write

class test:
    from platform import system

it looks exactly like

class test:
    def system():
        # ....

and then you have following problems:

  1. you can't use just system() because system is not in global scope
  2. you can't use self.system() because in this form, python automatically passes self as first argument, but system() has no parameters and you'll get TypeError: system() takes no arguments (1 given)
  3. you can't use test.system() because system() looks like a plain method, and you'll get TypeError: unbound method system() must be called with test instance as first argument (got nothing instead)

There are several ways around these problems:

  1. place import platform at top level, and use platform.system() wherever you want, thus fixing issue #1 from prev. list
  2. use staticmethod decorator, fixing issues #2 and #3 from prev. list.

like

class test:
    from platform import system
    system = staticmethod(system)

then you can use either self.system() or test.system()

Actually, you should just import everything in toplevel and forget about it. You only have to split import declarations if you need something special for running. Like

import foo
import bar

def fun(param1, param2):
    # .....

if __name__ == '__main__':
    from sys import argv
    if len(argv) > 2:
        fun(argv[1], argv[2])

In this example, moving from sys import argv is valid, because it is needed only when running a script. But when you use it as an imported module, there is no need in this import. But that is not your case, because in your case, system() is always needed for test class, so there is no reason to move this import from toplevel. Just leave it there and never mind.

like image 159
Alex Laskin Avatar answered Nov 02 '22 22:11

Alex Laskin


I'm surprised no one thought of this:

class test:
    def __init__(self):
        from platform import system
        self.system = system()
    def test(self):
        return self.system()

d = test()
print d.system()
print d.test()
like image 23
Logan Avatar answered Nov 03 '22 00:11

Logan