所以我想说的第一件事是:我一直在研究模块等,我只是不知道如何重写它以适应这一点。
项目:我拥有的是一个使用 Skype4Py 模块的 Skype 机器人。我有大约 11 个命令,我注意到其中一个脚本变得有点大。
我正在尝试考虑如何将一个 main.py 文件链接到一个插件文件夹,该文件夹在其自己的 Python 文件中包含每个机器人函数。听起来很简单,除了函数的调用方式之外。
这只是我的 Skype 机器人的基本介绍,缺少一些较大的功能。
import Skype4Py, random
class SkypeBot():
def __init__(self):
self.skype = Skype4Py.Skype()
if self.skype.Client.IsRunning == False:
self.skype.Client.Start()
self.skype.Attach()
self.results = ['Yes', 'No', 'Maybe', 'Never']
def main(self):
print ' Skype Bot currently running on user: %s' % self.skype.CurrentUserHandle
print "\n\nCommands Called:\n"
while True:
self.skype.OnMessageStatus = self.RunFunction
def RunFunction(self, Message, Status):
if Status == 'SENT' or Status == 'RECEIVED':
cmd = Message.Body.split(' ')[0]
if cmd in self.functions.keys():
self.context = Message
self.caller = self.context.FromHandle
self.functions[cmd](self)
def ping(self):
print " %s : Ping" % self.caller
self.context.Chat.SendMessage('Pong')
def say(self):
try:
response = self.context.Body.split(' ', 1)
if response[1] == "-info":
print " %s : say -info" % self.caller
self.context.Chat.SendMessage("Resends the message entered. \n"
"Usage: !say Hello. \n"
"Example: Bot: Hello.")
else:
say = response[1]
print " %s : Say [%s]" % (self.caller, say)
self.context.Chat.SendMessage(say)
except:
self.context.Chat.SendMessage("Please use -info to properly use the !say command")
def eightball(self):
try:
question = self.context.Body.split(' ', 1)
if question[1] == "-info":
print " %s : 8Ball -info" % self.caller
self.context.Chat.SendMessage("Responds with an answer.\n"
"Usage: !8ball 'Do I have swag?'\n"
"Example: !8Ball Response: 'Yes'")
else:
random.shuffle(self.results)
answer = self.results[3]
print " %s : 8Ball [%s]" % (self.caller, question[1])
self.context.Chat.SendMessage("!8Ball Response: %s" % answer)
except:
self.context.Chat.SendMessage("Please use -info to properly use the !8ball command")
#FUNCTIONS LIST
#********************
functions = {
"!ping": ping,
"!say": say,
"!8ball": eightball,
}
if __name__ == "__main__":
snayer = SkypeBot()
snayer.main()
基本上,我想知道的是,我该如何改变
self.skype.OnMessageStatus = self.RunFunction
以便它可以运行另一个文件中的函数?
最佳答案
对于这种大小的程序,实际上没有必要将命令函数放入单独的文件中,但我认为这是很好的组织。当您编写具有数千行代码的程序时,这是一个很好的实践。 :)
一种方法是创建一个不带任何命令方法的基本 SkypeBot 类,然后从插件目录中导入命令方法并将它们添加到该类中。向现有类添加新属性非常容易,并且无论新属性是属性还是方法,添加它们的语法都是相同的。 (只需多做一点工作,甚至可以向实例添加新属性,因此您可以拥有多个实例,每个实例都有自己单独的命令集。但我想这里没有必要,因为使用 SkypeBot 类的程序通常只会创建一个实例)。
因此我们可以将您的问题分为两部分:
- 如何向现有类添加方法。
- 如何导入这些方法 来自其他源文件。
正如我所说,1) 很简单。 2)也很简单,但我以前从未这样做过,所以我必须做一些研究和测试,我不能保证我所做的就是最佳实践,但它确实有效。 :)
我对Skype了解不多,而且我没有那个Skype4Py模块,正如你所说,上面的代码不是完整的程序,所以我写了一些相当简单的代码来说明这个过程将插件方法从单独的文件添加到现有的类中。
主程序的名称是“plugin_demo.py”。为了保持整洁,它位于自己的目录“plugintest/”中,您应该在 Python 路径中的某个位置(例如,通常保存 Python 程序的位置)创建该目录。此路径必须在您的 PYTHONPATH 环境变量中指定。
“plugintest/”具有以下结构:
plugintest/
__init__.py
plugin_demo.py
plugins/
__init__.py
add.py
multiply.py
Python 的 import
机制使用 __init__.py
文件来让它知道某个目录包含 Python 包,请参阅 6.4. Packages在 Python 文档中了解更多详细信息。
以下是这些文件的内容。首先,进入“plugintest/”本身的文件:
__init__.py
__all__ = ['plugin_demo', 'plugins']
from plugintest import *
plugin_demo.py
#! /usr/bin/env python
#A simple class that will get methods added later from plugins directory
class Test(object):
def __init__(self, data):
self.data = data
def add_plugins(cls):
import plugins
print "Adding plugin methods to %s class" % cls.__name__
for name in plugins.__all__:
print name
plug = getattr(plugins, name)
print plug
method = getattr(plug, name)
print method
setattr(cls, name, method)
print
print "Done\n"
add_plugins(Test)
def main():
#Now test it!
t = Test([1, 2, 3]); print t.data
t.multiply(10); print t.data
t.add(5); print t.data
if __name__ == '__main__':
main()
现在“plugintest/plugins/”目录的内容:
__init__.py
__all__ = ['add', 'multiply']
from plugintest.plugins import *
add.py
#A method for the Test class of plugin_demo.py
def add(self, m):
self.data = [m + i for i in self.data]
乘法.py
#A method for the Test class of plugin_demo.py
def multiply(self, m):
self.data = [m * i for i in self.data]
如果您 cd
到包含“plugintest/”文件夹的目录,您应该能够运行它
pythonplugintest/plugin_demo.py
如果您cd
到“plugintest/”本身
pythonplugin_demo.py
此外,在解释器(或另一个Python程序)中,您应该能够执行以下操作
导入插件测试
然后使用
运行“plugin_demo.py”的main()
函数
plugintest.plugin_demo.main()
from ... import ...
等的其他常见变体也应该按预期工作。
“plugin_demo.py”中执行将导入方法添加到 Test
类的神奇功能的函数是 add_plugins()
。当它运行时,它会打印出每个方法的名称、其模块及其函数。这在开发过程中可能很方便,但是一旦程序正常工作,您可能会注释掉其中一些打印语句。
希望这对您有所帮助,如果您有任何疑问,请随时询问。
关于python - 如何将我的 Python 文件分离到多个插件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26599820/