Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Python ➜ How to invoke a class method from trigger?

How to invoke a class method from trigger?

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Cadari   (25 posts)  Bio
Date Tue 08 Jul 2008 07:53 PM (UTC)
Message
Hello. How would you call a class method from a trigger?

class MyClass:
    def __init__(self):
        pass
    def trigger_procedure(self, name, line, wildcards):
        world.Note('Trigger fired.')
        
obj = MyClass()

<triggers>
  <trigger
   enabled="y"
   match="^$"
   regexp="y"
   script="obj.trigger_procedure"
   sequence="100"
  >
  </trigger>
</triggers>

The code above will yield an error "procedure not found". I can register my method in globals...

globals()['obj.trigger_procedure'] = obj.trigger_procedure

...and it will work, but that's just unacceptable. Any way to solve this? Thank you.
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #1 on Tue 08 Jul 2008 10:40 PM (UTC)
Message
I don't think it is possible.

MUSHclient looks for a function 'obj.trigger_procedure' in the global namespace, which doesn't exist. What you want is that MUSHclient queries the trigger_procedure from the 'obj' object, tells Python to call it with Python-regulations (self first), and then to tack on the rest of the parameters.

Maybe you could workaround this with a combination of annotations and importing the functions of your classes into the global namespace, but in annotated form. I know this sounds a bit vague, as I'm not sure how to go about it, but it should technically be possible. I think, anyhow.
Top

Posted by Cadari   (25 posts)  Bio
Date Reply #2 on Fri 11 Jul 2008 11:12 AM (UTC)

Amended on Fri 11 Jul 2008 11:19 AM (UTC) by Cadari

Message
Seems I have to use the ugly approach of doing things this way:

ids = []

class MyClass:
    def __init__(self, name):
        ids.append(id(self))
        self.name = name
    def trigger_procedure(self, name, line, wildcards):
        world.Note('Trigger fired.')
        
myobj = MyClass('myobj')

gc.collect()

for obj in gc.get_objects():
    if id(obj) in ids:
        method_name, method_obj = inspect.getmembers(obj, inspect.ismethod)[1:][0]
        globals()['%s.%s' % (obj.name, method_name)] = method_obj

Or a bit less ugly:

obj_names = []

class MyClass:
    def __init__(self, name):
        self.name = name
        obj_names.append(name)
    def trigger_procedure(self, name, line, wildcards):
        world.Note('Trigger fired.')
        
myobj = MyClass('myobj')

for obj_name in obj_names:
    exec('method_name, method_obj = inspect.getmembers(%s, inspect.ismethod)[1:][0]' % obj_name)
    globals()['%s.%s' % (obj_name, method_name)] = method_obj

At least until I find another way.
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #3 on Sat 12 Jul 2008 04:22 PM (UTC)
Message
Rather than bruteforcing exec in the way you are, I think you should be able to do the same thing with getattr()? I'm only looking at your code briefly and not fully understanding the details of it (not too familliar with the inspect module) but exec() is plain nasty imho.
Top

Posted by Cadari   (25 posts)  Bio
Date Reply #4 on Sat 12 Jul 2008 05:43 PM (UTC)
Message
The exec version is ugly, I agree. As is the whole approach. But I always thought that there's no way to get an object by its name without exec() or eval(), no?

It can be done storing objects themselves, not their names:

objs = []

class MyClass:
    def __init__(self, name):
        self.name = name
        objs.append(self)
    ...
        
myobj = MyClass('myobj')

for obj in objs:
    method_name, method_obj = inspect.getmembers(obj, inspect.ismethod)[1:][0]
    globals()['%s.%s' % (obj.name, method_name)] = method_obj

But, as I said, I don't like any of these versions.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


17,712 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.