有任何Python等价于分部类吗?
使用“新”样式的类(我使用的是python 3.2)有没有办法将一个类拆分为多个文件?我有一个很大的类(从面向对象的设计角度来看,它应该是一个单独的类,考虑到耦合等等,但是为了便于编辑类,最好分割几个文件。我没有使用过它,但声称添加了对部分类的支持 似乎还有其他一些方法可以自己实现 您可以将类的各个部分实现为单独文件中的mixin,然后将它们全部导入到某个地方并对它们进行子类化 或者,您可以在某个地方实现类的每个方法,然后在一个中心文件中导入它们,并将它们指定为类的属性,以创建整个对象。如下所示: a、 py: b、 py: c、 py: 如果您真的愿意,您甚至可以自动执行此过程—循环使用模块有任何Python等价于分部类吗?,python,partial-classes,Python,Partial Classes,使用“新”样式的类(我使用的是python 3.2)有没有办法将一个类拆分为多个文件?我有一个很大的类(从面向对象的设计角度来看,它应该是一个单独的类,考虑到耦合等等,但是为了便于编辑类,最好分割几个文件。我没有使用过它,但声称添加了对部分类的支持 似乎还有其他一些方法可以自己实现 您可以将类的各个部分实现为单独文件中的mixin,然后将它们全部导入到某个地方并对它们进行子类化 或者,您可以在某个地方实现类的每个方法,然后在一个中心文件中导入它们,并将它们指定为类的属性,以创建整个对象。如下所示
a
和b
提供的所有函数,然后将它们作为属性添加到C
上。尽管这可能太过分了
可能还有其他(可能更好)的方法,但这些是突然出现在脑海中的两种方法。包含数百行的类定义确实“在野外”出现(我在流行的基于Python的开源框架中看到了一些),但我相信,如果您仔细考虑这些方法的作用,将有可能将大多数类的长度减少到可管理的程度。一些示例:
- 寻找同一代码多次出现的地方。将该代码分解成它自己的方法,并在每个地方使用参数调用它
- 不使用任何对象状态的“Private”方法可以作为独立函数带出类
- 只有在特定条件下才应该调用的方法可能表示需要将这些方法放在子类中
要直接解决您的问题,可以拆分类的定义。一种方法是通过定义类,然后将外部函数作为方法添加到类中来“修补”该类。另一种方法是使用内置的
type
函数“手动”创建类,在字典中提供它的名称、任何基类以及它的方法和属性。但我不建议这样做,因为否则定义会很长。在我看来,这种治疗比疾病更糟糕。首先,我想说的是,这种复杂的事情可能不是一个好主意,仅仅为了找到你的在课堂上放置更容易-最好添加评论、突出显示部分等。但是,我认为有两种方法可以做到这一点:
exec
结果字符串最简单的方法是第一种选择。如果你的问题真的只是在编辑器中处理一个大类,那么我实际上要寻找的第一种解决方案是更好的解决问题的方法。第二种解决方案是更好的编辑器,最好是带有代码折叠的编辑器 也就是说,有几种方法可以将一个类拆分为多个文件。Python允许您将文件夹作为模块使用,方法是在其中放入
\uuu init\uuuuuuuuuuupy
,然后可以从其他文件导入内容。我们将在每个解决方案中使用此功能。首先创建一个名为bigclass
的文件夹
.py
文件。每个文件都应包含最终类的函数和变量定义,而不是类。在同一文件夹中的\uuuuuu init\uuuuuuuuuupy
中编写以下内容将它们连接在一起
class Bigclass(object):
from classdef1 import foo, bar, baz, quux
from classdef2 import thing1, thing2
from classdef3 import magic, moremagic
# unfortunately, "from classdefn import *" is an error or warning
num = 42 # add more members here if you like
这样做的好处是,您最终得到了一个直接从对象
派生的类,这在继承图中看起来很不错Bigclass
编写一个类定义。然后在\uuuuu init\uuuuuuuuuuupy
中编写:
import classdef1, classdef2, classdef3
class Bigclass(classdef1.Bigclass, classdef2.Bigclass, classdef3.Bigclass):
num = 42 # add more members if desired
classdef2.py
将类似于:
import classdef1
class Bigclass(classdef1.Bigclass):
# more member defs here
classdef3
将从classdef2
导入Bigclass
,并添加到其中,依此类推。您的\uuuuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuupy
将只导入最后一个:
from classdef42 import Bigclass
要在这些场景中使用该类,您可以使用文件夹名作为模块名导入它:
from bigclass import bigclass
我以前也曾尝试过类似的方法。我的用例是抽象语法树中节点的类层次结构,然后我想将所有例如prettyprinting函数放在分离prettyprint.py文件,但仍将其作为类中的方法
我尝试过的一件事是使用一个装饰器,将装饰过的函数作为指定类的一个属性。在我的例子中,这意味着prettyprint.py包含大量def prettyprint(self)
都用不同的@inclass(…)
这样做的一个问题是,必须确保始终导入子文件,并且子文件已被删除
import classdef1, classdef2, classdef3
class Bigclass(classdef1.Bigclass, classdef2.Bigclass, classdef3.Bigclass):
num = 42 # add more members if desired
import classdef1
class Bigclass(classdef1.Bigclass):
# more member defs here
from classdef42 import Bigclass
def inclass(kls):
"""
Decorator that adds the decorated function
as a method in specified class
"""
def _(func):
setattr(kls,func.__name__, func)
return func
return _
## exampe usage
class C:
def __init__(self, d):
self.d = d
# this would be in a separate file.
@inclass(C)
def meth(self, a):
"""Some method"""
print "attribute: %s - argument: %s" % (self.d, a)
i = C(10)
print i.meth.__doc__
i.meth(20)
class Car(object):
def start(self):
print 'Car has started'
def extends(klass):
def decorator(func):
setattr(klass, func.__name__, func)
return func
return decorator
#this can go in a different module/file
@extends(Car)
def do_start(self):
self.start()
#so can this
car = Car()
car.do_start()
#=> Car has started