我已经看到很多人从模块中提取所有类的例子,通常是这样的:
# foo.py
class Foo:
pass
# test.py
import inspect
import foo
for name, obj in inspect.getmembers(foo):
if inspect.isclass(obj):
print obj
Run Code Online (Sandbox Code Playgroud)
真棒.
但我无法找到如何从当前模块中获取所有类.
# foo.py
import inspect
class Foo:
pass
def print_classes():
for name, obj in inspect.getmembers(???): # what do I do here?
if inspect.isclass(obj):
print obj
# test.py
import foo
foo.print_classes()
Run Code Online (Sandbox Code Playgroud)
这可能是非常明显的事情,但我找不到任何东西.谁能帮我吗?
有没有一种直接的方法来查找属于python包的所有模块?我发现这个旧的讨论并不是真正的结论,但在推出基于os.listdir()的自己的解决方案之前,我希望得到明确的答案.
我终于升级了我的python版本,我发现了添加的新功能.除此之外,我正在摸索新__init_subclass__方法.来自文档:
只要包含类被子类化,就会调用此方法.然后cls是新的子类.如果定义为普通实例方法,则此方法将隐式转换为类方法.
所以我开始尝试一下,按照文档中的示例:
class Philosopher:
def __init_subclass__(cls, default_name, **kwargs):
super().__init_subclass__(**kwargs)
print(f"Called __init_subclass({cls}, {default_name})")
cls.default_name = default_name
class AustralianPhilosopher(Philosopher, default_name="Bruce"):
pass
class GermanPhilosopher(Philosopher, default_name="Nietzsche"):
default_name = "Hegel"
print("Set name to Hegel")
Bruce = AustralianPhilosopher()
Mistery = GermanPhilosopher()
print(Bruce.default_name)
print(Mistery.default_name)
Run Code Online (Sandbox Code Playgroud)
生成此输出:
Called __init_subclass(<class '__main__.AustralianPhilosopher'>, 'Bruce')
'Set name to Hegel'
Called __init_subclass(<class '__main__.GermanPhilosopher'>, 'Nietzsche')
'Bruce'
'Nietzsche'
Run Code Online (Sandbox Code Playgroud)
我知道这个方法是在子类定义之后调用的,但我的问题特别是关于这个特性的用法.我也阅读了PEP 487文章,但对我没什么帮助.这种方法在哪里有用?是为了:
另外,我是否需要了解它__set_name__以充分理解其用法?
我有一些类看起来像这样:
class Base:
subs = [Sub3,Sub1]
# Note that this is NOT a list of all subclasses!
# Order is also important
class Sub1(Base): pass
class Sub2(Base): pass
class Sub3(Base): pass
...
Run Code Online (Sandbox Code Playgroud)
现在,这失败了,因为Base.subs时没有定义Sub1和Sub3.但显然我不能把子类放在Base之前.有没有办法在Python中转发声明类?我想使用,isinstance因此subs中的类型实际上必须与后面声明的子类相同,它们具有相同的名称和其他属性是不够的.
一个解决方法是:Base.subs = [Sub3,Sub1] 在定义了子类之后,但我不喜欢以这种方式拆分我的类.
编辑:添加了有关订单的信息
有没有办法在python中查询从特定类继承的类的命名空间?给定一个类,widget我希望能够调用类似于inheritors(widget)获取所有不同类型的小部件的列表.
python中的any命令行选项是否打印异常/错误类层次结构?
输出应类似于http://docs.python.org/2/library/exceptions.html#exception-hierarchy
我正在尝试编写一个通用的元类来跟踪子类
因为我希望这是通用的,我不想这个元类中硬编码任何类的名字,所以我想出了生成正确的元类,像一些功能:
def make_subtracker(root):
class SubclassTracker(type):
def __init__(cls, name, bases, dct):
print('registering %s' % (name,))
root._registry.append(cls)
super(SubclassTracker, cls).__init__(name, bases, dct)
return SubclassTracker
Run Code Online (Sandbox Code Playgroud)
这样我就可以调用它来为特定的根类生成一个元类:
__metaclass__ = make_subtracker(Root)
Run Code Online (Sandbox Code Playgroud)
这是我遇到问题的地方.我不能做到这一点:
class Root(object):
_registry = []
__metaclass__ = make_subtracker(Root)
Run Code Online (Sandbox Code Playgroud)
...因为Root我使用时还没有定义make_subtracker(Root).我稍后尝试添加metaclass属性,以便至少可以在子类中应用它:
class Root(object):
_registry = []
Root.__metaclass__ = make_subtracker(Root)
Run Code Online (Sandbox Code Playgroud)
......但这不起作用.读取类定义时,metaclass有一个特殊的处理,如http://docs.python.org/reference/datamodel.html#customizing-class-creation中所定义
我正在寻找建议来做到这一点(在运行时以一种应用于其子类的方式更改类'元类,或任何其他替代方法).
我有一个涉及Python元类的深奥问题.我正在为Web服务器端代码创建一个Python包,通过客户端代理可以轻松访问任意Python类.我的代理生成代码需要我想要包含在我的API中的所有Python类的目录.要创建此目录,我使用__metaclass__特殊属性将钩子放入类创建过程中.具体来说,"已发布"API中的所有类都将子类化为特定的基类PythonDirectPublic,该基类本身__metaclass__具有已设置的类以记录有关类创建的信息.
到现在为止还挺好.它变得复杂的地方是我希望PythonDirectPublic自己继承第三方类(enthought.traits.api.HasTraits).这个第三方类也使用了__metaclass__.
那么管理两个元类的正确方法是什么?我的元类应该是Enthought元类的子类吗?或者我应该在我的元类的__new__方法中调用Enthought的元类来获取我将返回的类型对象?或者在这种特殊情况下是否还有其他一些神秘的咒语?
我使用peewee定义了很多模型类.ClassName.create_table()可以生成表,但只能生成一个表.如何使用单个语句创建所有表?
我工作的一个基于文本的冒险游戏,并拥有一个具有所有的动作类,例如模块Move(Action),Look(Action).我需要一种方法,将模块中作为类的子类的所有类实例Action化为如下列表:
actions = [Move(), Look()]
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点,而无需通过键入他们的名称单独实例化类?
python ×10
metaclass ×3
class ×2
adventure ×1
exception ×1
inheritance ×1
inspect ×1
module ×1
orm ×1
packages ×1
peewee ×1
python-3.5 ×1
python-3.6 ×1
reflection ×1
subclass ×1
traits ×1