我在使用此设置时遇到问题,主要是因为我不确定实际需要什么才能解决此问题。
这是设置
- 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
中自动提供给我我确信这不是一件难事,但老实说,我不知道我想要什么(寻求解决这个问题),这使我无法研究解决方案。
答案 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的元类答案基本上是一种非常好的自动方式,虽然它的工作原理是在创建类之前向类块添加额外的定义,而不是在之后向类对象添加额外的属性。
基本上你应该开发一个框架,在这个框架中,一个模块中定义的东西会自动添加到其他地方定义的类中。但是你仍然需要做出一些设计决定,例如:
像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