2013-09-20 5 views
0

Возможно, это основной вопрос, но я новичок в программировании. Я работаю с сторонним кодом python и предоставляет класс делегатам событий и событий. Синтаксис для событий и делегатов мероприятий являются следующим:События и делегаты Python

public Delegate Sub RequestEventDelegate (request As MDNPRequest, _ 
     response as MDNPResponseParser) 

    public Event RequestEvent As MDNPRequest.RequestEventDelegate 

Я написал следующий код subcribe к событию, но не работаю. Я не знаю, что я делаю .

Mreq = MDNPRequest() 
    Mreq.RequestEvent += Mreq.RequestEventDelegate(handleResponseEvent) 

    def handleResponseEvent (request, response): 
     print ' event fired' 

Я добавляю две строки кода в конец функции, которая открывает канал связи. Я также тестировал добавление двух строк кода к функции, которая посылает опрос на канале связи. Во втором сценарии событие срабатывает и каждый раз, когда я выполняю функцию опроса. Означает ли это нарушение цели подписки на события?


Я думаю, что моя проблема может быть связана с различными функциями, создающими экземпляры того же класса. Я хотел бы объединить некоторые из функций в класс, используя схему, показанную ниже. Метод1 создает экземпляр 'a' класса1, который мне бы хотелось использовать в других методах myClass. Я попытался использовать переменную класса, которую я установил для экземпляра класса1, но это не работает. Я ссылаюсь на переменную класса, используя имя класса, например myClass.variable.somemethod, из класса1, но получаю ошибку «Ссылка на объект, не установленную на экземпляр объекта». Каков наилучший подход, чтобы все методы в myClass могли иметь доступ к? В конце концов, я хотел бы позвонить myClass из другого модуля.

from file1 import * 

    myClass: 

     class_variable = class1() # class1 from file1 

     def __init__(self) 
     ... 

     def Method1(self, argument list): 
     # this method instantiates a 
      ... 
      a = class1() 

     def Method2 (self): 
      ... 
      a.class1method1 
      ... 

     def Method3 (self): 
      ... 
      a.class1method2 
      ... 
+0

Является ли это синтаксисом IronPython и C#, с которым вы пытаетесь соответствовать? Или что-то другое? – abarnert

+0

@abarnert Я стараюсь соответствовать VB. – cjbust

+0

Спасибо. В общем, это помогает помещать эту информацию в вопрос - и, тем более, для того, чтобы поместить ссылку туда, откуда поступает информация. В этом случае ничто из этого не может быть связано с вашей проблемой, но это никогда не повредит. – abarnert

ответ

0

Из ваших последних изменений я подозреваю, что вам не хватает оснований того, как работают классы на Python. Вы можете прочитать the tutorial chapter или, возможно, искать более дружелюбный/более подробный учебник.

В частности:

Я хотел бы объединить некоторые функции в классе, используя схему, показанную ниже. Метод1 создает экземпляр 'a' класса1, который мне бы хотелось использовать в других методах myClass. Я попытался использовать переменную класса, которую я установил для экземпляра класса1, но это не работает.

Это не способ сделать это. Атрибуты класса, такие как ваши class_variable, создаются во время создания класса (то есть, как правило, как только вы import модуль или запустите сценарий), а не время создания экземпляра. Если вы хотите создать что-то, когда созданы экземпляры вашего класса, вы используете атрибуты экземпляра, а не атрибуты класса, и вы установили их в методе __init__.В вашем случае вам не нужен экземпляр, созданный до вызова Method1 экземпляра, что означает, что вы используете атрибут экземпляра; вы просто делаете это внутри Method1, а не __init__.

Кроме того, атрибуты класса разделяются всеми экземплярами класса; атрибуты экземпляра, каждый экземпляр имеет свой собственный. Вещь о собаках: у каждой собаки есть собственный хвост, у всех собак нет одного хвоста, поэтому tail является атрибутом экземпляра. Часто в простых сценариях вы не замечаете разницы, потому что вы только когда-либо создаете один экземпляр класса. Но если вы не можете понять разницу практически, подумайте об этом концептуально (например, пример Dog), и если вы все еще не можете понять это, вы почти всегда хотите атрибут экземпляра.

Ссылка на переменную класса с использованием имени класса, например myClass.variable.somemethod, из класса 1, но я получаю ошибку «Ссылка на объект, не установленную на экземпляр объекта».

Скорее всего, это происходит потому, что class1 является COM/Interop или классов .NET, и вы пытаетесь создать и использовать его, прежде чем делать какие-либо из соответствующей установки, которая происходит только потому, что вы пытаетесь сделайте это, как только вы import модуль/запустите скрипт. Если это так, если вы создаете его, когда на самом деле намеревались, проблем не будет.

Каков наилучший подход, чтобы все методы myClass могли иметь доступ к?

Создать атрибут экземпляра в Method1, как это:

def Method1(self, argument list): 
    # this method instantiates a 
    ... 
    self.a = class1() 

И затем использовать его таким же образом:

def Method2 (self): 
    ... 
    self.a.class1method1() 
    ... 

Просто делать a = whatever только создает локальную переменную, которая уходит в конец метода. Даже если это имеет то же имя, что и атрибут класса, атрибут экземпляра или глобальный, вы все еще создаете новую локальную переменную, не изменяя вещь, которую хотите изменить. В отличие от некоторых других языков, Python требует, чтобы вы явно указывали на то, что вы пытаетесь переписать, для атрибута экземпляра, myClass.a для атрибута класса и т. Д., Поэтому вы не делаете это случайно.

Также обратите внимание на круглые скобки в конце этого последнего выражения. Если вы хотите вызвать функцию или метод, вам нужны скобки; в противном случае вы просто ссылаетесь на этот метод как значение.


В конце концов, я хотел бы назвать MyClass из другого модуля.

Я не уверен, что вы подразумеваете под словом "class myClass". Когда вы вызываете класс, он создает новый экземпляр класса. Затем вы можете вызвать методы этого экземпляра так же, как и любой другой объект. Неважно, какой модуль он был определен (за исключением того, что вам, очевидно, нужно писать my_instance = mymodule.MyClass()).

Посмотрите, как вы используете стандартную библиотеку; это точно то же самое. Например, если вы import csv, вы можете построить DictWriter, написав my_writer = csv.DictWriter(my_file). И затем вы вызываете его методы, написав my_writer.writerow(my_row).Как только вы его построили, неважно, из какого модуля он исходил.


еще одно:

Вы пытались определить класс, как это:

myClass: 

Вы, очевидно, не может сделать это; вам нужно ключевое слово class. Но также, в Python 2.x, вы всегда хотите дать базовые классы, используя object, если вам больше ничего не нужно. В противном случае вы получаете класс старого стиля, который вызывает всевозможные странные причуды и ограничения, которые вы не хотите изучать и которые нужно отлаживать. Итак:

class myClass(object): 
+0

@abarnet Спасибо за ввод. Я не знал, что можно установить класс вне __init__, и это является причиной моей попытки использовать переменную класса. У меня уже есть тестовый код. – cjbust

+0

@CarlosBustamante: Что вы подразумеваете под «создать экземпляр класса вне' __init__'? »? Создание экземпляра класса - это только часть my_object = myClass() ', которая никогда не происходит внутри' __init__'. (Ну, это может произойти внутри '____init__' некоторого _other_ класса.) Вы имели в виду« добавить переменную экземпляра? Это та, которая имеет тенденцию удивлять людей, поступающих с таких языков, как Java. В Python вы можете добавлять новые переменные к любому объекту (за исключением объектов некоторых встроенных типов) в любое время - даже из полностью вне класса. – abarnert

+0

@abarnet Я думал, что переменные экземпляра должны быть определены внутри __init__. Как вы указали, переменные экземпляра могут быть назначены в любое время. – cjbust

2

Если это на самом деле ваш код:

Mreq.RequestEvent += Mreq.RequestEventDelegate(handleResponseEvent) 

def handleRequestEvent (request, response): 
    print ' event fired' 

... handleResponseEvent это не то же самое, как handleRequestEvent.


В качестве побочного примечания вам почти не нужно создавать явный делегат. Иногда это полезная оптимизация, но это еще одна причина, по которой вы можете ошибаться, и еще одна вещь, которая может маскировать полезную отладочную информацию, когда вы это делаете, поэтому обычно проще писать код без нее и добавлять только ее в качестве делегата после его работы, если вы обнаружите, что создаете их много, и хотите сохранить некоторую память.

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