2

I have a class as given below and I want to access some of variables located inside function of that class. The structure is as below:

class access_all_elements:

   def RefSelect_load_file(): 

       reffname = askopenfilename(filetypes=(("XML files", "*.xml"),
                                                 ("All files", "*.*") ))
       if reffname: 
          ReferenceXML.insert(END,fileOpen.read())  
          recovering_parser = etree.XMLParser(recover=True)
          AdasReference = etree.parse(reffname, parser=recovering_parser).getroot()
          AdasReferenceString = etree.fromstring(ToStringAdasReference)
          TimeReferenceTest = AdasReferenceString.findall("{http://www.google.com/car}bmw")
      return TimeReferenceTest

  def CopySelect_load_file(): 
    #same code as above, but for loading another file in same GUI

Description of code

1). class access_all_elements: class to access all elements inside

2). def RefSelect_load_file(): function inside class that loads xml file

3). ReferenceXML.insert(END,fileOpen.read()) insert filepath in text box inside gui

4). AdasReference: Parse xml file located in reffname

5). TimeReferenceTest: this extracts all the elements from xml having label car The output of this variable looks like: [<Element {http://www.google.com/car}bmw at 0x279ff08>, <Element {http://www.google.com/car}bmw at 0x279ffa8>.....]

5). return TimeReferenceTest I want to return the value of this variable when function is called

What I want:

There is another function outside this class namely callback which uses one of the variable which is located in access_all_elements class and that variable is TimeReferenceTest. I want to access the value of this variable in the below given function. The value is mentioned in 5th point above. The function outside class looks like below:

        def callback():

            toplevel = Tk()
            toplevel.title('Another window')
            RWidth=Root.winfo_screenwidth()
            RHeight=Root.winfo_screenheight()
            toplevel.geometry(("%dx%d")%(RWidth,RHeight))

            for i,j in zip(TimeReferenceTest,TimeCopyTest): #TimeCopyTest is also like TimeReferenceTest defined in above class under CopySelect_load_file() function,but not mentioned here
                    .......

To put it simply, out of entire entity of RefSelect_load_file() function I only want to access the value of variable TimeReferenceTest in line for i,j in zip(TimeReferenceTest,TimeCopyTest) when callback is function is executed

What I tried and What this is all about

First all, I am making a GUI in Tkinter and trying to bind all the code I wrote with that gui. Callback is invoked when someone presses button to compare two xml files.

What I tried so far is the approach of encapsulating both functions into same class as shown above to access its variables. I call the class in following manner:

c = access_all_elements()
c.RefSelect_load_file()

The problem here is I know this function is defined in a way to open file dialogue box, but I want to return value of only TimeReferenceTest when I call it in callback function. So is there any way you can suggest where i can access that variable without executing entire function?

Radheya
  • 779
  • 1
  • 11
  • 41
  • Your problem is not clear. Why are you not using a member (possibly class member) for the class that is set up once instead of a function? – Reut Sharabani Jul 30 '15 at 12:32
  • I don't entirely understand your question, but generally speaking a method in a class can access a variable created in a different method of that same class, as long as it was created as an attribute of the class instance: e.g. `self.thing_i_want_to_be_visible = whatever`. Although I notice your methods have no `self` parameter, which is a little odd... – Kevin Jul 30 '15 at 12:33
  • @ReutSharabani this functions were binded with the button code in tkinter so thats why i retained the function as it is and created a class which will cover all such functions inside. I followed this tutorial http://stackoverflow.com/questions/10139866/calling-variable-defined-inside-one-function-from-another-function – Radheya Jul 30 '15 at 12:36
  • @Kevin yea you are right but then I was curious why would there be no other way to access value of functions located in one class into another function which is outside class. This way then i might end up declaring all functions in same class. – Radheya Jul 30 '15 at 12:38
  • Scopes outside the class can access the value too, provided they have a reference to the class instance: `c.thing_i_want_to_be_visible` – Kevin Jul 30 '15 at 12:40
  • @Kevin but what about above case where there is a function under a class and I want to access a value of variable inside that function outside the class? – Radheya Jul 30 '15 at 12:42
  • You wouldn't ever want to do that. If you need to access a variable outside a method, you make it an instance attribute. – Daniel Roseman Jul 30 '15 at 12:48
  • @DanielRoseman Can you please show a quick short e.g of how it can be done? I think I am missing something major over here. – Radheya Jul 30 '15 at 12:50
  • You generally can't access a class instance's attributes if you don't have a reference to the instance, because if you could, how would Python know which instance you were referring to? One class can have multiple instances, and the only way to distinguish between them is to explicitly reference the one you want. – Kevin Jul 30 '15 at 12:53
  • so u mean I should call a class in following manner `c = access_all_elements()` `c.RefSelect_load_file(TimeReferenceTest)` ? adding the reference of variable i want value of – Radheya Jul 30 '15 at 12:59

2 Answers2

2

I think you might be looking for something that does not exist. If you want 2 functions to share specific variables you do not have too many options.

As you have already mentioned one option is to put both functions into a class and make the variables you want shared "members":

Class MyFuncs:
    def __init__(self, someVal):
        self.val = someVal
    def foo(self):
        self.val = "FOO"
    def bar(self):
        self.val = self.val + "BAR"

Another option might be to use closures:

def GetFunctions():
    sharedArray = [] # put shared values here
    def foo():
        sharedArray.append("FOO")
    def bar():
        sharedArray.append("BAR")
    def printAll():
        for word in sharedArray:
            print(word)
    return (foo,bar,printAll)

Though I do not really recommend this method.

Of course you could also just pass things into the function as parameters. If the functions aren't logically coupled then this is what you should be doing anyway.

If none of these options suit your fancy then the problem is with your design. Your code should be organized in a way that is intuitive and should make logical sense! If you want this functionality simply for convenience (perhaps you do not want to put too many parameters on your functions) then you probably will not find the answer you are looking for.

Hope this helps! :)

Michael S Priz
  • 1,116
  • 7
  • 17
  • Thanks. but your logic is more or less same as the one given in http://stackoverflow.com/questions/10139866/calling-variable-defined-inside-one-function-from-another-function. but here I would like to know just for my understanding whether is it possible to access value of `val` outside class. Take for instance value of `val` in `def foo(self)` outside the entire class where it is located in – Radheya Jul 30 '15 at 13:07
  • No, that is not possible. – fishsticks Jul 30 '15 at 13:21
  • 1
    @DhruvJ, in this case `val` is a member of an instance of the class `MyFuncs`. This means that when you create an object of type MyFuncs my doing `myFuncsObj = MyFuncs()` anything that is in the same scope as `myFuncsObj` can access `val` using `myFuncsObj.val`. Does this answer your question? You seem unfamiliar with OOP. I am here to help :) – Michael S Priz Jul 30 '15 at 14:31
  • @MichaelSPriz Sorry for late response. Yes I understood what you mean. I am kinda new with using oop functionalities in python. I am trying implement your logic in my program. thank you – Radheya Jul 31 '15 at 09:05
1

I think you should make the functions part of the instance rather than static class methods. You can then make TimeReferenceTest also an attribute, which you can then access from outside the instance:

class Access_all_elements():
    def __init__(self):
        self.timeReferenceTest = None
        self.timeCopyTest = None

    def refSelect_load_file(self):
        ...
        self.timeReferenceTest = adasReferenceString.findall(...)
        ...
...
c = Access_all_elements()

# get value as return value from function
trt = c.RefSelect_load_file()
print("  TimeReferenceTest = %s" % trt)
...
# use the value in callback
def callback():
    ...
    for i,j in zip(c.timeReferenceTest,c.timeCopyTest): ...

This assumes c is global, though it would be better if you passed it in.

(Note: Your naming scheme seems backwards which makes your code hard to grasp. PEP8 suggests that classes should begin with an uppercase, and functions and attributes should begin with lowercase. I tried to adopt that in my answer to make the code easier to understand for most python programmers)

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • your logic is very useful. Using your logic I just drafted a more simple example on my own. http://paste.ofcode.org/uKakRgFDHehjvVcLK8jCbC in here when I `print c.a` why am I getting answer as `1` and not `change`. I know that if i put parenthesis after function name I will get correct value, but the problem is in tkinter button callback I can only use function name in `c.refSelect_load_file` format and not in `c.refSelect_load_file()` – Radheya Jul 31 '15 at 14:47