How to Call a Classes Method from Another Class Without Initialising the First Class

How do I call a classes method from another class without initialising the first class?

SOLUTION

Thanks all for your help, I have a better understanding of it now. What I did in the end as suggested in comments was to remove these particular methods from the classes and make them global functions. I actually went through and removed all methods that weren't specifically referencing self (or made sense to leave them as class methods) and made them global. Looking at it now I think this is a better way to structure the code.

Thanks all.

Calling a class function without triggering the __init__

Yes, it is possible.

Using a helper function

You could write a helper function that replace __init__ method of your class with a dummy method and then instantiates the class and after this we re-assign the old __init__ back to class.

def skip_init(cls):
actual_init = cls.__init__
cls.__init__ = lambda *args, **kwargs: None
instance = cls()
cls.__init__ = actual_init
return instance

Demo:

>>> a = skip_init(Potato)
>>> a.myfunction()
I do something

Overriding __new__

You could override __new__ method of your class and there based on argument you can replace __init__ with a dummy method.

def new_init(cls, init):
def reset_init(*args, **kwargs):
cls.__init__ = init
return reset_init


class Potato():
def __new__(cls, *args, **kwargs):
instance = object.__new__(cls)
lazy = kwargs.pop('_no_init', False)
if not lazy:
return instance
cls.__init__ = new_init(cls, cls.__init__)
return instance

def __init__(self):
print("Initializing")

def myfunction(self):
print("I do something")

Demo:

>>> a  = Potato(_no_init=True)
>>> a.myfunction()
I do something
>>> b = Potato()
Initializing
>>> b.myfunction()
I do something

Call Class Method From Another Class

update: Just saw the reference to call_user_func_array in your post. that's different. use getattr to get the function object and then call it with your arguments

class A(object):
def method1(self, a, b, c):
# foo

method = A.method1

method is now an actual function object. that you can call directly (functions are first class objects in python just like in PHP > 5.3) . But the considerations from below still apply. That is, the above example will blow up unless you decorate A.method1 with one of the two decorators discussed below, pass it an instance of A as the first argument or access the method on an instance of A.

a = A()
method = a.method1
method(1, 2)

You have three options for doing this

  1. Use an instance of A to call method1 (using two possible forms)
  2. apply the classmethod decorator to method1: you will no longer be able to reference self in method1 but you will get passed a cls instance in it's place which is A in this case.
  3. apply the staticmethod decorator to method1: you will no longer be able to reference self, or cls in staticmethod1 but you can hardcode references to A into it, though obviously, these references will be inherited by all subclasses of A unless they specifically override method1 and do not call super.

Some examples:

class Test1(object): # always inherit from object in 2.x. it's called new-style classes. look it up
def method1(self, a, b):
return a + b

@staticmethod
def method2(a, b):
return a + b

@classmethod
def method3(cls, a, b):
return cls.method2(a, b)

t = Test1() # same as doing it in another class

Test1.method1(t, 1, 2) #form one of calling a method on an instance
t.method1(1, 2) # form two (the common one) essentially reduces to form one

Test1.method2(1, 2) #the static method can be called with just arguments
t.method2(1, 2) # on an instance or the class

Test1.method3(1, 2) # ditto for the class method. It will have access to the class
t.method3(1, 2) # that it's called on (the subclass if called on a subclass)
# but will not have access to the instance it's called on
# (if it is called on an instance)

Note that in the same way that the name of the self variable is entirely up to you, so is the name of the cls variable but those are the customary values.

Now that you know how to do it, I would seriously think about if you want to do it. Often times, methods that are meant to be called unbound (without an instance) are better left as module level functions in python.

Call class method from another class without inheritance and global in python

I amended your indentation (to what I think you meant) and did this:

class A():
def P(self, param):
print(param)
class B():
def Q(self):
obj = A()
obj.P("printThis")

And it seems to me to work:

>>> b = B()
>>> b.Q()
printThis

Calling a method from another class WITHOUT creating a new instance

So, you have two instaces -- one with a button, and one with a label. I'm assuming they are both descendants of NSViewController or otherwise manage underlying views.

The problem is, you found no way to address second instance containing label from the method of first instance.

You need to define a property in first instance's class:

@property(weak) SecondClass *secondInstance;

And then in button clicked method:

-(void)clickedButton
{
[self.secondInstance changeText];
}

There is one issue left: who is responsible to set first instance's property that we defined? This depends on who did create both of them, probably just app delegate or enclosing controller, you know that better.

UPD: If both of the controllers are created by AppDelegate:

#import "FirstClass.h"
#import "SecondClass.h"

@interface AppDelegate ()

// case A - manual
@property(strong) FirstClass *firstInstance;
@property(strong) SecondClass *secondInstance;

// case B - declared in xib
//@property(weak) IBOutlet FirstClass *firstInstance;
//@property(weak) IBOutlet SecondClass *secondInstance;

@end

@implementation AppDelegate

...

- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
// Create them
self.firstInstance = [[FirstClass alloc] init...];
self.secondInstance = [[SecondClass alloc] init...];
// Or maybe they are declared in MainMenu.xib, then you do not create them
// by hand, but must have outlets for both. See case B above.

// Connect them
self.firstInstance.secondInstance = self.secondInstance;

...
}

Note that class is not the same as an object (instance). Class is a named collection of methods, mostly for the instance. In Objective-C, class is not just a name, but an object too, so you can call a method on it (i.e. send an message to the class object). But here we always talk about objects (instances), so forget about classes – we hold objects via strong properties or weak outlets, depending on how they were created, and operate on objects, never on classes.

How to call an Object's Method from another class without creating a sub-class and/or inheriting class?

Excellent question format.

You can declare an Object of type People, and use that.

Example

public class MainPage
{
People people = new People();

// .. Some code.

if(optionSelected == 3) {
people.friend();
}
}

Explanation

Your friend method is an instance method. This means that in order to access it, you need to have an instance of the object created. This is done with the new keyword. Secondly, unless People is some form of utility class, then your friend method should probably read more like:

 public void friend()
{
System.out.println(this.friend);
}

And for the sake of good code design, remember that your MainPage class is outputting to the user, so you should return the value rather than print it. Secondly, you should conform to good naming standards, and in Java we use the get prefix when getting a class member.

public void getFriend()
{
return this.friend;
}

and in the MainPage class, you should print this.

if(optionSelected == 3)
{
System.out.println(people.getFriend());
}


Related Topics



Leave a reply



Submit