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
  super() and order of running method in class inheritance akbarza 7 595 Feb-04-2024, 09:35 AM
Last Post: Gribouillis
  problem usage of static method akbarza 5 456 Feb-03-2024, 07:43 AM
Last Post: paul18fr
  Int.From_Bytes Method - Conversion of Non-Escaped Bytes Objects new_coder_231013 1 272 Jan-17-2024, 09:13 PM
Last Post: Gribouillis
  Building a DoublyLinkedList in Python - - append method Drone4four 2 375 Jan-08-2024, 01:27 PM
Last Post: Drone4four
Information Best distribution method inovermyhead100 0 530 Jul-19-2023, 07:39 AM
Last Post: inovermyhead100
  method call help sollarriiii 6 1,080 Feb-21-2023, 03:19 AM
Last Post: noisefloor
  That compression method is not supported tester_V 9 3,315 Jan-31-2023, 07:05 PM
Last Post: tester_V
  sys.argv method nngokturk 3 1,028 Jan-23-2023, 10:41 PM
Last Post: deanhystad
  Method works as expected on host machine but not on server gradlon93 4 1,051 Jan-05-2023, 10:41 AM
Last Post: DeaD_EyE
  Custom method to handle exceptions not working as expected gradlon93 3 945 Dec-22-2022, 07:12 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

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