Python Forum
creating a variable in a method and using in another method
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
creating a variable in a method and using in another method
#1
Good evening......
Can someone please tell me the correct way to create a variable within a method and then be able to re-use that variable internal to the class within another method? As an example I tried this below with __usb and __SG....in particular __SG gets defined in open method and I want to re-use it in close method...Thank you for all responses

	def open(self):
		k = visa.ResourceManager()
		try:
			__usb = k.list_resources()[1]
		except IndexError:
			print ('Make sure equipment is turned on')			
		try:
			__SG = k.open_resource(__usb)
		except:
			print ('USB Resource could not be opened')
		else:		
			print ('Success opening USB resource')
		
	def close(self):
		__SG.close()
		print ('Success closing resource')	
Reply
#2
To do that, you would need to instantiate the variable as a field:

class Example:
    def do_stuff(self):
        self.x = 22

    def do_more_stuff(self):
        return self.x * 4
Your code has a potential bug. Because __SG and __usb are in try blocks, there is no guarantee they will be instantiated. In turn, if __usb isn't instantiated, line 8 will raise an error; if __SG isn't instantiated, close() will raise an error.
Reply
#3
Well, the first observarion is, these appear to be methods within a class (thus the use of "self" in the "def open(self):" and "def close(self):". The "self" refers to the object of that class, after it has been instantiated. In order for a variable of that class's instantiated object to be visible to something outside the instantiated object for that class, you must tie it to the "self."

I.e.
class MyObject:
    def __init__(self):
        self.k = visa.ResourceManager()

    def open(self):
        
        try:
            self.__usb = self.k.list_resources()[1]
        except IndexError:
            print ('Make sure equipment is turned on')          
        try:
            self.__SG = self.k.open_resource(__usb)
        except:
            print ('USB Resource could not be opened')
        else:       
            print ('Success opening USB resource')
             
    def close(self):
        self.__SG.close()
        print ('Success closing resource') 
    
>>> import MyObject
>>> o = MyObject()
>>> print(o.__SG) 
HOWEVER, you have named this variable with a preceding double underscore "__" this tells other developers you specifically do not want them messing with the "self.__SG" variable directly. If you DO want objects outside the class instantiated object to interact with this variable, remove the double underscore. If you really don't want things messing with it directly, sou should set a getter/setter, as such...

class MyObject:
    def __init__(self):
        self.k = visa.ResourceManager()

    @property
    def sg(self):
        try: return self.__SG
        except (ValueError, AttributeError):
            raise AttributeError("The property 'sg' has not be set.")

    @sg.setter
    def sg(self, value):
        raise AttributeError("The value of the property 'sg' can not be set externally")
    
    def open(self):
        
        try:
            self.__usb = self.k.list_resources()[1]
        except IndexError:
            print ('Make sure equipment is turned on')          
        try:
            self.__SG = self.k.open_resource(__usb)
        except:
            print ('USB Resource could not be opened')
        else:       
            print ('Success opening USB resource')
             
    def close(self):
        self.__SG.close()
        print ('Success closing resource') 
    
>>> import MyObject
>>> o = MyObject()
>>> print(o.sg)
<some value appears>
>>> o.sg = "My new value"
<raises error>
Reply
#4
(Oct-04-2019, 08:02 AM)burningkrome Wrote: In order for a variable of that class's instantiated object to be visible to something outside the instantiated object for that class, you must tie it to the "self."
Actually self (note that we use 'self' pure as convention, same for 'cls' to refer the class) ties it to the specific instance of the class (instance attribute), otherwise it would be class attribute accessible to all instances of the class


Some experiments to show difference between the class and instance attributes (incl. mutable vs. immutable)
class Foo:
    foo = 1
    my_list = []
    def __init__(self, bar):
        self.bar = bar
        print(f'class attribute foo at the start of __init__:{Foo.foo}')
        Foo.foo += 2
        print(f'class attribute foo after add 2 in __init__:{self.foo}')
        Foo.my_list.append(bar)
        self.my_list.append(bar*2)

    @classmethod
    def tripple(cls):
        print(f'class attribute foo beforer tripple:{cls.foo}')
        cls.foo *= 3
        print(f'class attribute foo after tripple:{cls.foo}')



spam = Foo(5)
print(f'class foo:{spam.foo}')
print(f'bar: {spam.bar}')
print(f'my_list: {spam.my_list}')
spam.tripple()
# create spam.foo instance attribute
# it overrides the  class foo attribute when you use spam.foo
spam.foo += 1
print(f'instance foo: {spam.foo}')

# class attribute still exists but is not accesible via spam.foo
spam.tripple()
print(f'instance foo:{spam.foo}')
spam.my_list.append('spam')
print('--- eggs instance ---')
eggs = Foo('eggs')
print(eggs.foo)
print(eggs.bar)
print(eggs.my_list)
Output:
class attribute foo at the start of __init__:1 class attribute foo after add 2 in __init__:3 class foo:3 bar: 5 my_list: [5, 10] class attribute foo beforer tripple:3 class attribute foo after tripple:9 instance foo: 10 class attribute foo beforer tripple:9 class attribute foo after tripple:27 instance foo:10 --- eggs instance --- class attribute foo at the start of __init__:27 class attribute foo after add 2 in __init__:29 29 eggs [5, 10, 'spam', 'eggs', 'eggseggs']
Note the behaviour of mutable class attribute my_list. It can create problems or create opportunities (e.g. shared attribute between all instances of a class)
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#5
Thanks everyone for your comments....Please bear with me as I am new to this....I am experimenting with some of the comments above, in particular

class test:
	t = visa.ResourceManager()
	
	def __init__(self):
			self.k = visa.ResourceManager()
			m = visa.ResourceManager()
I have a file sandbox.py....I import sandbox....
I can see t by using sandbox.test.t (please jump in and correct me if I go awry)...By not using the parentheses after test (ie sandbox.test() implies I have NOT created an instance, is this correct?)

Now to see k I must do something like j = sandbox.test(); j.k....Is this correct? (seems to work)

I ALSO notice here that j.t works too...guessing that is because the instance is a subset of the class so all is good

How do I access m? Does it have to live outside the instance creation (__init__)? Seems it could live anywhere assuming you don't put self tag on it....

Last question: can I declare 'self' attributes in methods other than __init__ ? and are they accessible by external and internal?

thanks again for all the help out there! Everyone is very responsive....this is a great forum
Reply
#6
I see big confusion with respect to OOP basics. I would suggest you check a tutorial on class basics., e.g. we have one - https://python-forum.io/Thread-Classes-Class-Basics
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Accessing method attributes of python class Abedin 6 887 Apr-14-2025, 07:02 AM
Last Post: buran
  __eq__ method related problem Tsotne 6 914 Mar-09-2025, 03:48 PM
Last Post: Tsotne
  Changing client.get() method type based on size of data... dl0dth 1 723 Jan-02-2025, 08:30 PM
Last Post: dl0dth
  Error in the method "count" for tuple fff 2 835 Nov-24-2024, 03:29 AM
Last Post: fff
  Trying to understand method Giri234 1 720 Oct-04-2024, 02:10 AM
Last Post: deanhystad
  creating arbitrary local variable names Skaperen 9 1,827 Sep-07-2024, 12:12 AM
Last Post: Skaperen
  Destructor method adding in string chizzy101010 3 932 Sep-03-2024, 12:31 PM
Last Post: chizzy101010
  Difference between method and attribute holding a function ulrich 2 938 Jun-30-2024, 08:35 AM
Last Post: snippsat
  comtypes: how to provinde a list of string to a COM method zalanthas 0 962 Jun-26-2024, 01:27 PM
Last Post: zalanthas
Question No disconnect method for snowflake.connector ? Calab 0 828 Jun-11-2024, 09:42 PM
Last Post: Calab

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020