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