FAQ
Hi,

I have two classes in separate python modules and I need to access some
methods of the either classes from the other. They are not in base and
derived class relationship.

Please see the example below. Foo imports Bar and inside the Foo class it
creates a Bar obj and then calls Bar.barz(). Now before returning control,
it has to call the track method in Foo.

As I understand, I won't be able to use 'super' in this case, as there is no
inheritance here. Also, I won't be able to move the track method to Bar as I
need to track different bar types.

Any suggestion on how to get this done would be great. Thanks in advance.

Cheers
- b

----------

* foo.py *

import bar
class Foo:
def fooz():
print "Hello World"
b = Bar()
c = b.barz()
...

def track(track_var):
count += 1
return sth2


* bar.py *
class Bar:
def barz():
track_this = ...
if Foo.track(track_this):
pass
else:
...
return sth1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20101028/44779191/attachment.html>

Search Discussions

  • Dave Angel at Oct 29, 2010 at 2:12 am

    On 2:59 PM, Baskaran Sankaran wrote:
    Hi,

    I have two classes in separate python modules and I need to access some
    methods of the either classes from the other. They are not in base and
    derived class relationship.

    Please see the example below. Foo imports Bar and inside the Foo class it
    creates a Bar obj and then calls Bar.barz(). Now before returning control,
    it has to call the track method in Foo.

    As I understand, I won't be able to use 'super' in this case, as there is no
    inheritance here. Also, I won't be able to move the track method to Bar as I
    need to track different bar types.

    Any suggestion on how to get this done would be great. Thanks in advance.

    Cheers
    - b

    ----------

    * foo.py *

    import bar
    class Foo:
    def fooz():
    print "Hello World"
    b = Bar()
    c = b.barz()
    ...

    def track(track_var):
    count += 1
    return sth2


    * bar.py *
    class Bar:
    def barz():
    track_this = ...
    if Foo.track(track_this):
    pass
    else:
    ...
    return sth1
    Your example is so vague it's hard to tell what the real requirements
    are. Foo.track() won't work as coded, since it doesn't have a self
    argument. If you really meant that, then make it a non-class function,
    and preferably define it in another module, included perhaps by both bar
    and foo. Similarly, barz() cannot be called, since it wants zero
    arguments, and it'll always get at least one.

    If I were you, I'd put both classes into the same module until you get
    their relationship properly understood. And if they're really so
    intertwined, consider leaving them in the same module. This isn't java.

    In general, it's best not to have two modules importing each other.
    Generally, you can extract the common things into a separate module that
    each imports. Failing that, you can have one import the other, and pass
    it whatever object references it'll need to run. For example, at the
    end of foo.py, you'd have something like
    bar.Foo = Foo


    If you really need to mutually import two modules, the first problem
    you're likely to bump into is if either of them is your script. In
    other words, you need to have a separate file that's your script, that
    imports both foo and bar.

    DaveA
  • Baskaran Sankaran at Oct 29, 2010 at 3:33 am
    Sorry for the confusion; fooz(), track() and barz() are all members of their
    respective classes. I must have missed the self argument while creating the
    synthetic example.

    Yeah, I realize the mutual import is a bad idea. So, if I merge them into a
    single module (but still retaining the two classes) will work right? I
    guess, it will look like this after merging.

    Thanks again
    -b

    * foo_bar.py *

    class Foo:
    def fooz(self):

    print "Hello World"
    b = Bar()
    c = b.barz()
    ...

    def track(self, track_var):
    count += 1
    return sth2


    class Bar:
    def barz(self):

    track_this = ...
    if Foo.track(track_this):
    pass
    else:
    ...
    return sth1

    On Thu, Oct 28, 2010 at 7:12 PM, Dave Angel wrote:

    Your example is so vague it's hard to tell what the real requirements are.
    Foo.track() won't work as coded, since it doesn't have a self argument. If
    you really meant that, then make it a non-class function, and preferably
    define it in another module, included perhaps by both bar and foo.
    Similarly, barz() cannot be called, since it wants zero arguments, and
    it'll always get at least one.

    If I were you, I'd put both classes into the same module until you get
    their relationship properly understood. And if they're really so
    intertwined, consider leaving them in the same module. This isn't java.

    In general, it's best not to have two modules importing each other.
    Generally, you can extract the common things into a separate module that
    each imports. Failing that, you can have one import the other, and pass it
    whatever object references it'll need to run. For example, at the end of
    foo.py, you'd have something like
    bar.Foo = Foo

    If you really need to mutually import two modules, the first problem you're
    likely to bump into is if either of them is your script. In other words,
    you need to have a separate file that's your script, that imports both foo
    and bar.

    DaveA
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: <http://mail.python.org/pipermail/python-list/attachments/20101028/1a6f6a07/attachment-0001.html>
  • Chris Rebert at Oct 29, 2010 at 4:06 am

    On Thu, Oct 28, 2010 at 8:33 PM, Baskaran Sankaran wrote:
    Sorry for the confusion; fooz(), track() and barz() are all members of their
    respective classes. I must have missed the self argument while creating the
    synthetic example.

    Yeah, I realize the mutual import is a bad idea. So, if I merge them into a
    single module (but still retaining the two classes) will work right? I
    guess, it will look like this after merging.

    Thanks again
    -b

    * foo_bar.py *

    class Foo:
    ??? def fooz(self):
    ??????? print "Hello World"
    ??????? b = Bar()
    ??????? c = b.barz()
    ??????? ...

    ??? def track(self, track_var):
    ??????? count += 1
    That line will raise UnboundLocalError. Where's count initialized?
    ??????? return sth2


    class Bar:
    ??? def barz(self):
    ??????? track_this = ...
    ??????? if Foo.track(track_this):
    You can't call an instance method on a class.

    Cheers,
    Chris
    --
    Nitpicker extraordinaire
    http://blog.rebertia.com
  • Dave Angel at Oct 29, 2010 at 6:12 pm

    On 2:59 PM, Chris Rebert wrote:
    On Thu, Oct 28, 2010 at 8:33 PM, Baskaran Sankaranwrote:
    Sorry for the confusion; fooz(), track() and barz() are all members of their
    respective classes. I must have missed the self argument while creating the
    synthetic example.

    Yeah, I realize the mutual import is a bad idea. So, if I merge them into a
    single module (but still retaining the two classes) will work right?
    Yes, if you define them both in the same module, they can reference each
    other arbitrarily. But you still have plenty of errors, some of which
    Chris has pointed out. I can ignore most, but his point about calling a
    function without an instance is important, so I'll comment some more at end.
    I
    guess, it will look like this after merging.

    Thanks again
    -b

    * foo_bar.py *

    class Foo:
    def fooz(self):
    print "Hello World"
    b =ar()
    c =.barz()
    ...

    def track(self, track_var):
    count +=
    That line will raise UnboundLocalError. Where's count initialized?
    return sth2


    class Bar:
    def barz(self):
    track_this =..
    if Foo.track(track_this):
    You can't call an instance method on a class.
    If you really need to call this on the class (because its data spans
    multiple instances, for example), then you should make it a
    classmethod. Easiest way is as follows:

    class Foo:
    def fooz(self):
    print "Hello World"
    b = Bar()
    c = b.barz()
    ...

    @classmethod
    def track(cls, track_var):
    count += 1

    Note that the first argument is now the class, so by convention we call
    it cls, rather than self. And that within a class method, you typically
    reference class attributes. So you might want to use something like:

    class Foo:
    count = 0 #I'm a class attribute
    def fooz(self):
    print "Hello World"
    b = Bar()
    c = b.barz()
    ...

    @classmethod
    def track(cls, track_var):
    cls.count += 1



    DaveA

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedOct 28, '10 at 11:59p
activeOct 29, '10 at 6:12p
posts5
users3
websitepython.org

People

Translate

site design / logo © 2022 Grokbase