2010-10-04 7 views
24

В Python существует способ вызова метода класса из другого класса? Я пытаюсь создать собственную MVC-структуру в Python, и я не могу понять, как вызвать метод из одного класса в другом классе.Метод класса вызова из другого класса

Вот что я хочу, чтобы это произошло:

class A: 
    def method1(arg1, arg2): 
     # do code here 

class B: 
    A.method1(1,2) 

Я медленно попасть в Python из PHP, так что я ищу эквивалент Python в РНР call_user_func_array().

+0

ли это на самом деле должен быть метод класса, а не функция?Статические методы на других языках не обязательно сопоставляются методу класса в Python. Дайте это прочитать: http://dirtsimple.org/2004/12/python-is-not-java.html –

+5

@Ivo Честно говоря, вам все равно, пишет ли он свой MVC, прежде чем он научится основам? пусть он попытается изучить основы этого процесса. перестань быть таким снисходительным к людям, задающим вопросы. – aaronasterling

+4

@AaronMcSmooth это был честный совет - нет даже разумного ответа на его текущий вопрос, потому что это не имеет смысла, что часто случается. Я попытался написать ответ, но все, что я мог, было советом, чтобы сначала изучить основы python. В следующий раз я добавлю «очень понравится»;) –

ответ

33

обновление: просто посмотрел ссылку на call_user_func_array в ваше сообщение. это другое. использовать getattr, чтобы получить объект-функцию, а затем вызвать его с вашими аргументами

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

methodname = 'method1' 
method = getattr(A, methodname) 

method теперь является фактическим объектом функции. которые вы можете вызвать напрямую (функции - это объекты первого класса в python, как в PHP> 5.3). Но соображения снизу все еще применяются. То есть приведенный выше пример взорвется, если вы не украсите A.method1 одним из двух декораторов, рассмотренных ниже, передайте ему экземпляр A в качестве первого аргумента или примените getattr к экземпляру A.

a = A() 
method = getattr(a, methodname) 
method(1, 2) 

У вас три варианта для этого

  1. Используйте экземпляр A для вызова method1 (с использованием двух возможных форм)
  2. применять classmethod декоратор method1: вы будете не дольше можете ссылаться на self в method1, но вы получите экземпляр cls в его месте, которое находится A в этом случае.
  3. применять staticmethod декоратор method1: вы больше не будете иметь возможность ссылаться на self или cls в staticmethod1, но вы можете жёстко ссылки на A в него, хотя, очевидно, эти ссылки будут унаследованы всеми подклассами A, если они специально переопределить method1 и не звонить super.

Некоторые примеры:

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) 

Обратите внимание, что таким же образом, что имя переменной self полностью зависит от вас, так это имя переменной cls но это обычные значения.

Теперь, когда вы знаете, как это сделать, я бы серьезно подумал о , если вы хотите это сделать. Часто, методы, которые должны быть названы unbound (без экземпляра), лучше оставить в качестве функций уровня модуля в python.

+0

Что такое значение cls в '@classmethod def method3 (cls, a, b): return cls.method2 (a, b)' –

4

Просто позвоните его и поставить self

class A: 
    def m(self, x, y): 
     print(x+y) 

class B: 
    def call_a(self): 
     A.m(self, 1, 2) 

b = B() 
b.call_a() 

выход: 3

+0

Этот пример неверен, поскольку вы передаете ссылку класса B методу класса A –

+0

I предположим, что он будет работать до тех пор, пока все атрибуты, называемые self.x в методе, также существуют на B – a1an

+0

@VarunMaurya, Python использует утиную печать, поэтому классы не проверяются. Как говорит a1an, пока вы поставляете объект с правильными атрибутами, это будет работать. – ratiotile

Смежные вопросы