简体   繁体   中英

Python + Twisted … importing classes from different files?

We're working on a project and using Twisted for the first time. Though we're both beginners we know that it's generally good practice to have basically one class + functions per file. In Twisted, what we read in the documentation suggested that it's not really possible to do this, because you can't have more than one instance of twisted running.

Is it okay to just write your code as if twisted is running, then in the file that is running twisted run all your functions etc. there?

To clarify:

Say I'm running my instance of twisted in

main.py

I need to have certain twisted protocols imported:

from twisted.internet.protocol import Factory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
from twisted.internet import task
import random
import sqlite3
import string

And I'll make a class (but let's just say function for right now) that uses some function from things I imported from twisted. So for example, LineReceiver has a method sendLine:

def connectionLost(self, leave):
....
        if self.users.has_key(self.name):
        message = "%s has disconnected" % (self.name)
        del self.users[self.name]
        print (message)
        for name, protocol in self.users.iteritems():
            protocol.sendLine(message)

This all runs just fine, so long as it's in the same file as the imports from twisted. Because, from what we know, that's how things are done. If I were to import time, for example, in one file and then make another file I would have to do import time there as well.

I don't know about LineReceiver specifically, but we are under the impression that you can only run one instance of a reactor, which we use methods from (such as reactor.callLater) many times throughout the program.

The problem we run into, however, is more of tidiness. Our program quickly grew to be just over the 4,000 line mark and still growing, and of course this leads to a lot of time consumption looking for things within all these lines of code. So we'd like to basically make a different file for each class. But we aren't sure if this will work because of the lack of twisted being ran in each file.

Or is it possible to simply copy/paste each class into its own file, with the methods like sendLine running, and then import them/call them in the main file where twisted is running?

Importing twisted.internet.reactor and calling methods on it directly is frequently a sign of trouble. Your callers will lose control of what your callees are doing, and it makes writing tests for your code much harder.

Instead, you should refactor everything that needs to use a reactor to take it as a parameter or as an attribute, ie:

class Foo(object):
    def __init__(self, reactor, ....):
        self.reactor = reactor

And then, only import twisted.internet.reactor in one place, as late as possible:

def main():
    do_some_stuff()
    from twisted.internet import reactor
    stuff_done = start_some_stuff(reactor)
    stuff_done.addCallback(reactor.stop)

if __name__ == '__main__':
    main()

other than twisted.internet.reactor , its perfectly fine to import everything where you need it, If two modules need LineReceiver , they can both import it safely.

we know that it's generally good practice to have basically one class + functions per file.

no, that's horrible. You are comming from PHP, aren't you?

because you can't have more than one instance of twisted running.

Is it okay to just write your code as if twisted is running, then in the file that is running twisted run all your functions etc. there?

I have no idea what you are talking about.

From your examples, I guess your problem is you don't understand python scoping - there is a scope per module (file) so if you import x , x is available in the file the import is written in. If you need x in other file, you need to import it there too (or pass it there by funciton call).

Look up how scoping and imports work and difference between module and package.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM