0

Check the following example working code of our implementation of nested classes with mixed staticmethods.

import time

class A:
    def __init__(self):
        time.sleep(0.1)

    def a1(self):
        print 'a1'

    @staticmethod
    def a2(): 
        print 'a2'

    class B:
        @staticmethod
        def b2():
            A.a2()         #fine.  
            A().a1()       #very bad solution, computation cost is high !!!

        @staticmethod
        def x():
            t = time.clock()
            for i in xrange(100):
                A.B.b2()
            print 'elapsed: %0.1fs'%(time.clock()-t)

to use as:

A.B.x()

The above works but as you may notice for line A().a1() in which we have tried to get access to a non-static method a1 from container class A the computation cost is too high. We emphasized this point by having sleep in A initialization. So you get the point, it can be any time consuming initialization which is necessary in our work, for example. So we don't believe instantiating class A in the mentioned line is a good choice. How to not to instantiate A in the above but having the job done as exactly as above. The question above has bot been answered anywhere although related ones include this and that.

EDIT:
We are not interested in recommendations such as why use it etc. The question of our interest as clearly pointed out above is how to improve just this line

A().a1()

that's all.

Solved in the following way based on advice given by Martijn Pieters. We accepted the answer due to showing the way to solve.

class B:
    @staticmethod
    def b2(Ai):
        A.a2()         #fine.
        if Ai is None: Ai = A()
        Ai.a1()        #now is fine.

    @staticmethod
    def x():
        t = time.clock()
        Ai = A()
        for i in xrange(100):
            A.B.b2(Ai=Ai)
        print 'elapsed: %0.1fs'%(time.clock()-t)

Thank You.

12
  • 2
    Sorry, what? You want to execute code requiring an instance of A without instanciating A? Commented Sep 28, 2013 at 9:16
  • I am entirely unclear as to what you are asking, but nested static methods do not behave any different from non-nested static methods. There is no additional performance penalty (other than the attribute lookup, which is not exactly costly) that'd make the situation exceptional. Commented Sep 28, 2013 at 9:19
  • @MartijnPieters Note that in the code above we are looking for a solution not to instantiate A million times just to access to method a1. There should somehow to do this only with one instance. Commented Sep 28, 2013 at 9:20
  • If A takes long to initialize then do it only once, caching the instances. You can do this with a very simple __new__ method. Commented Sep 28, 2013 at 9:20
  • 1
    That's just a caching problem; that has nothing to do with static methods or nested objects. Commented Sep 28, 2013 at 9:21

1 Answer 1

2

Your problem has nothing to do with static methods or nested classes. The exact same problem exists for global functions:

class A:
    def __init__(self):
        time.sleep(0.1)

    def a1(self):
        print 'a1'

def a2(): 
    print 'a2'

def b2():
    a2()  
    A().a1()

def x():
    t = time.clock()
    for i in xrange(100):
        b2()
    print 'elapsed: %0.1fs'%(time.clock()-t)

Calling x() will still cause expensive instances of A() to be created in a loop outside of b2().

You need to devise a caching strategy for creating A(). There are too many ways of doing that to sum up here, certainly with so little information on when reusing an instance of A() is acceptable over creating a new one.

If you wanted to reuse an instance of A() just for the loop in x() then pass that along as an optional argument:

def x():
    t = time.clock()
    instance = A()
    for i in xrange(100):
        b2(instance)
    print 'elapsed: %0.1fs'%(time.clock()-t)

def b2(instance=None):
    a2()
    if instance is None:
        instance = A()
    instance.a1()

Now the instance is cached for the duration of function x().

Sign up to request clarification or add additional context in comments.

5 Comments

We are afraid that this is not what we want. We are not interested in changing the structure of our code. The missing point is that with this there is no container structure, you see. where is A.B.x()?
And you already know that the example in the question is to demonstrate our purpose not the original code which may have thousands of methods and structures in it. See the point. No changing the structure is allowed. We are curious to fill our lack of knowledge about the line A().a1() mentioned above nothing else.
I simplified the situation to illustrate this has nothing to do with containment. Just add that back in. The structure of nested classes has nothing to do with your problem.
You need to figure out when instances of A() can be reused, and then do that; reuse those instances. It doesn't matter at all how you are using the instance, the same problem applies to your nested structure as it does to my simplified flattened structure.
Now we your comments / answer we could solve the problem. Our solution was added at the end of the question. Thanks so much.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.