Libin Thomas
Libin Thomas

Reputation: 969

How do I access the variable inside a class method from another python file?

I have two python files main.py and conftest.py. I want to access a variable of a method of the class Test declared in main.py from a function declared in conftest.py.
I have tried a bit, but I know it's wrong as I get a syntax error in the first place. Is there any way to do this?

main.py
class Test():

    def test_setup(self):
        #make new directory for downloads
        new_dir = r"D:\Selenium\Insights\timestamp}".format(timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
        # print(new_dir)
        if not os.path.exists(new_dir):
            os.makedirs(new_dir)
            saved_dir=new_dir
conftest.py
from main import Test

def newfunc():
    dir=Test.test_setup()
    print(dir.saved_dir)

Upvotes: 1

Views: 160

Answers (2)

surge10
surge10

Reputation: 642

Local variable save_dir must be declared as an attribute of the class Test:

class Test():

  def __init__(self):
    self.new_dir = ""
    self.saved_dir = ""

  def test_setup(self):
    #make new directory for downloads
    self.new_dir = r"D:\Selenium\Insights\timestamp}".format(timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
    # print(self.new_dir)
    if not os.path.exists(self.new_dir):
      os.makedirs(self.new_dir)
      self.saved_dir=self.new_dir

Then you have to instantiate an object of the class Test and by this object access save_dir:

def newfunc():
    dir=Test().test_setup()
    print(dir.saved_dir)

Upvotes: 2

User051209
User051209

Reputation: 2503

In the execution of your function newfunc() the first instruction dir=Test.test_setup() raise the following error:

dir=Test.test_setup()
TypeError: test_setup() missing 1 required positional argument: 'self'

This error referred to an attempt to execute a method of a class by attribute reference but it requests an argument which is in general an instance of that class.

To solve this, and other errors present in your code, and build an answer to your question I think that it is enough to do following steps:

  • define the variable save_dir as an attribute of the class Test
  • instantiate an object of the Test class.

In your code saved_dir is a local variable of the method test_setup so it is not visible outside of that method.

I show you the 2 possible correct files:

File main.py

from datetime import datetime
import os

class Test():
  def __init__(self):
    self.new_dir = ""
    self.saved_dir = ""

  def test_setup(self):   
    #make new directory for downloads
    #new_dir = r"D:\Selenium\Insights\timestamp}".format(timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
    timestamp=datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
    self.new_dir = "/home/frank/Selenium/Insights/timestamp/" + timestamp 
    # print(new_dir)
    if not os.path.exists(self.new_dir):
      os.makedirs(self.new_dir)
      self.saved_dir = self.new_dir
      
  def get_saved_dir(self):
    return self.saved_dir

Pay attention: don't use directly the previous code because in main.py I have adjusted the value of new_dir according to my environment (see /home/frank/Selenium/Insights/timestamp/ instead of your D:\Selenium\Insights\timestamp).

File conftest.py:

from main import Test

def newfunc():
    test_class = Test()
    test_class.test_setup()
    print(test_class.get_saved_dir())

newfunc()

If you want to access to the attribute saved_dir directly without the use of method get_saved_dir() (not very object oriented) the file conftest.py becomes:

from main import Test

def newfunc():
    test_class = Test()
    test_class.test_setup()
    # access directly to attribute saved_dir (not properly Object Oriented)
    print(test_class.saved_dir)

newfunc()

Accessing the attributes of a class by reference

This is a useful link (it is included in the tutorial of official Python documentation) about the access to a variable or a method of a class.

Previous link explains how to access to an attribute of a class by reference. If we adapt this concept to this post we can access the method test_setup of the class Test, by the following syntax:

f = Test.test_setup

If we print on the standard output the value of f we obtain:

print(f)

# this is the output
<function Test.test_setup at 0x7f93f54316a8>

and this means that f is a valid attribute reference to a function object. In particular I referred to the following sentence of the link:

MyClass.i and MyClass.f are valid attribute references, returning an integer and a function object, respectively.

Upvotes: 2

Related Questions