将其他文件中的函数添加到Python类中

时间:2012-03-26 01:04:32

标签: python class inheritance

我在使用此设置时遇到问题,主要是因为我不确定实际需要什么才能解决此问题。

这是设置

- main.py
- lib
  - __init__.py 
  - index.py
  - test.py

__ init __。py 有此代码

import os
for module in os.listdir(os.path.dirname(__file__)+"/."):
    if module == '__init__.py' or module[-3:] != '.py':
        continue
    __import__(module[:-3], locals(), globals())
del module

main.py 此代码截至目前

from lib.index import *
print User.__dict__

index.py 有此代码

class User(object):
    def test(self):
        return "hi"
    pass

test.py 有此代码

class User(object):
    def tes2(self):
        return "hello"

当我执行main.py时,它成功地从test打印方法index.py,但我想要做的是找出一种方法,我可以在lib文件夹中创建一个文件其中while只有一个格式为

的函数
class User(object):
    def newFunction(self):
       return abc

这个函数应该在main.py

中自动提供给我

我确信这不是一件难事,但老实说,我不知道我想要什么(寻求解决这个问题),这使我无法研究解决方案。

3 个答案:

答案 0 :(得分:2)

您可以使用元类来自定义类创建并添加在别处定义的函数:

import types
import os
import os.path
import imp

class PluginMeta(type):
    def __new__(cls, name, bases, dct):
        modules = [imp.load_source(filename, os.path.join(dct['plugindir'], filename))
                    for filename in os.listdir(dct['plugindir']) if filename.endswith('.py')]
        for module in modules:
            for name in dir(module):
                function = getattr(module, name)
                if isinstance(function, types.FunctionType):
                    dct[function.__name__] = function
        return type.__new__(cls, name, bases, dct)


class User(object):
    __metaclass__ = PluginMeta
    plugindir = "path/to/the/plugindir"

    def foo(self):
        print "foo"

user = User()
print dir(user)

然后在插件文件中,只创建函数而不是类:

def newFunction(self, abc):
    self.abc = abc
    return self.abc

元类会找到它们,把它们变成方法,并将它们附加到你的班级。

答案 1 :(得分:1)

类是对象,方法只不过是类对象的属性。

因此,如果要在原始类块之外向现有类添加方法,那么所有这一切都是向对象添加属性的问题,我希望您知道该怎么做:

class User(object):
    pass

def newFunction(self):
    return 'foo'

User.newFunction = newFunction

agf的元类答案基本上是一种非常好的自动方式,虽然它的工作原理是在创建类之前向类块添加额外的定义,而不是在之后向类对象添加额外的属性。

基本上你应该开发一个框架,在这个框架中,一个模块中定义的东西会自动添加到其他地方定义的类中。但是你仍然需要做出一些设计决定,例如:

  1. 如果外部定义的函数需要辅助定义,那么如何确定应该添加到类中的内容以及仅仅是依赖项?
  2. 如果你有多个课程,你会以这种方式进行扩展,你如何确定哪个课程的内容?
  3. 您的计划中的哪一点会发生自动延期?
  4. 你想在你的班级中说“这个类有其他地方定义的扩展”,或者在你的扩展中说“这是对其他地方定义的类的扩展”,或者两者都没有,并且在某处从两者外部绑定类的扩展? / LI>
  5. 您是否需要能够同时使用不同扩展名的“同一”类的多个版本?
  6. 像agf提出的元类可以是实现这种框架的一种非常好的方法,因为它允许你将所有复杂的代码放在一个地方,同时仍然“标记”每个类不起作用的类正常工作。但它确实解决了我上面提出的一些问题的答案。

答案 2 :(得分:0)

这里是我们在项目中使用的工作代码,我不确定它是最好的方法但是它有效并且几乎没有其他代码可以添加到其他文件

cpu.py:

from cpu_base import CPU, CPUBase

import cpu_common
import cpu_ext

cpu_base.py:

def getClass():
    return __cpu__

def setClass(CPUClass):
    global __cpu__
    __cpu__ = CPUClass
    __classes__.append(CPUClass)

def CPU(*kw):
    return __cpu__(*kw)

class CPUBase:
    def __init__(self):
        your_init_Stuff
        # optionally a method classname_constructor to mimic __init__ for each one
        for c in __classes__:
            constructor = getattr(c, c.__name__ + '_constructor', None)
            if constructor is not None:
                constructor(self)
setClass(CPUBase)

cpu_common.py:

from cpu_base import getClass, setClass
class CPUCommon(getClass()):
    def CPUCommon_constructor(self):
        pass
setClass(CPUCommon)

cpu_ext.py:

from cpu_base import getClass, setClass

class CPUExt(getClass()):
    pass
setClass(CPUExt)

使用cpu.py中的类导入CPU