使用另一个类的方法python中的类的方法

时间:2014-10-01 18:09:27

标签: python

我需要使用来自不同类(不同文件)中的类的函数,并且遇到问题,不知道如何实现这一点,并且正在努力寻找正确的帮助以寻找我正在寻找的东西(我可能使用错误的条款)。

Directory Structure:
--app
  --static
    --js
  --templates
    --main_page.html
  --__init__.py
  -- MainApp.py
  --settings.py
server.py

server.py:

from gevent import monkey
from socketio.server import SocketIOServer

from app import app
monkey.patch_all()
listen_address = '0.0.0.0'
listen_port = 5000
print 'Starting Server on: http://{0}:{1}'.format(listen_address, listen_port)
SocketIOServer((listen_address, listen_port), app, resource="socket.io").serve_forever()

app>的初始化的.py

from flask import Flask
from flask import render_template
from flask import request
from socketio import socketio_manage
import settings
from celery import Celery
from redis import Redis
import subprocess
import requests
from socketio.namespace import BaseNamespace


def make_celery(app):
    celery = Celery(app.import_name, broker=app.config['CELERY_BROKER_URL'])
    celery.conf.update(app.config)
    TaskBase = celery.Task
    class ContextTask(TaskBase):
        abstract = True
        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)
    celery.Task = ContextTask
    return celery



app = Flask(__name__)
app.debug = True
app.config.from_object(settings)
celery = make_celery(app)
r_server = Redis('localhost')

@app.route('/socket.io/<path:remaining>')
def socket(remaining):
    socketio_manage(request.environ, {'/testclass': TestClass}, request)
    return 'done'


@app.route('/')
def main_page():
    return render_template('main_page.html')

class TestClass(BaseNamespace):
    def on_submit(self, data):
        #start mainapp
        import MainApp
        MainApp.MainApp()

    @celery.task(name='tasks.emitter')
    def emitter(self, string):
 #           emit to receive function in javascript... javascript pulls the 'mytext' field which contains (string)
        self.emit('receive', {'mytext': string})
    from socketio.namespace import BaseNamespace
    import MainApp

MainApp.py

import app

class MainApp(app.TestClass):

    def __init__(self):
    self.emitter(self, 'test1234')

如何在Mainapp中使用TestClass中的self.emit?发射器函数运行self.emit,使用websockets发送一个字符串javascript代码...我不断收到如下错误......

TypeError: emitter() takes exactly 2 arguments (1 given) 

或者在上述情况下......

Traceback (most recent call last):
  File "/.../.../.../lib/python2.7/site-packages/gevent/greenlet.py", line 327, in run
    result = self._run(*self.args, **self.kwargs)
  File "/.../.../.../lib/python2.7/site-packages/socketio/virtsocket.py", line 403, in _receiver_loop
    retval = pkt_ns.process_packet(pkt)
  File "/.../.../.../lib/python2.7/site-packages/socketio/namespace.py", line 155, in process_packet
    return self.process_event(packet)
  File "/.../.../.../lib/python2.7/site-packages/socketio/namespace.py", line 225, in process_event
    return self.call_method_with_acl(method_name, packet, *args)
  File "/.../.../.../lib/python2.7/site-packages/socketio/namespace.py", line 240, in call_method_with_acl
    return self.call_method(method_name, packet, *args)
  File "/.../.../.../lib/python2.7/site-packages/socketio/namespace.py", line 282, in call_method
    return method(*args)
  File "/.../.../.../.../app/__init__.py", line 50, in on_submit
    MainApp.MainApp()
  File "/.../.../.../.../app/MainApp.py", line 11, in __init__
    self.emitter(self, 'test1234')
  File "/.../.../.../lib/python2.7/site-packages/celery/local.py", line 167, in <lambda>
    __call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw)
  File "/.../.../.../.../app/__init__.py", line 24, in __call__
    return TaskBase.__call__(self, *args, **kwargs)
  File "/.../.../.../lib/python2.7/site-packages/celery/app/task.py", line 420, in __call__
    return self.run(*args, **kwargs)
  File "/.../.../.../.../app/__init__.py", line 55, in emitter
    self.emit('receive', {'mytext': string})
  File "/.../.../.../lib/python2.7/site-packages/socketio/namespace.py", line 451, in emit
    endpoint=self.ns_name)
AttributeError: 'MainApp' object has no attribute 'ns_name'
<Greenlet at 0x1120ad0f0: <bound method Socket._receiver_loop of <socketio.virtsocket.Socket object at 0x111c7c5d0>>> failed with AttributeError

谢谢!

3 个答案:

答案 0 :(得分:0)

我建议您显式创建classA的实例,以免混淆。

class MainApp(object):
    def __init__(self,emitter):
        self.objA = ClassA()
        self.emitter = self.objA.emitter
        self.emitter('string')

您还可以将其设为类方法,或者如果需要共享则使用单独的函数:

@classmethod
@celery.task(name='tasks.emitter')
 def emitter(cls, string):
     cls.emit('receive', {'mytext': string})


class MainApp(object):
    def __init__(self,emitter):
        self.emitter = ClassA.emitter
        self.emitter('string')

答案 1 :(得分:0)

这里没有问题,因为它在另一个班级。您的MainApp类继承自TestClass,因此通过self.emitter引用该方法是完全正确的。

唯一的问题是你传递了self两次:任何方法调用,无论是否继承,都会自动传递self参数,所以你只需要传递另一个参数:

self.emitter('test1234')

答案 2 :(得分:0)

看起来你正试图倒退。

每个条件:您需要在某处定义 emit(someStr,someDict)

您的MainClass需要扩展ClassA。

假设你有class_a.py和main_app.py

<强> main_app.py

from class_a import ClassA

class MainApp(ClassA):
    ## now you can call any method from ClassA
    self.emitter(someArg)

注意:您不需要ClassA中的MainApp.MainApp(self.emitter),因为MainApp扩展了ClassA。