В моем случае: убедитесь, что ваш файл содержит хотя бы один класс перед компиляцией!
AFAIK, учитывая класс и никакую другую информацию, Вы не можете сказать, является ли это вложенным классом. Однако посмотрите здесь для того, как Вы могли бы использовать декоратора для определения этого.
Проблема состоит в том, что вложенный класс является просто нормальным классом, это - атрибут его внешнего класса. Другие решения, что Вы могли бы ожидать работать, вероятно, не будут- inspect.getmro
, например, только дает Вам базовые классы, не внешние классы.
Кроме того, вложенные классы редко необходимы. Я сильно пересмотрел бы, является ли это хорошим подходом в каждом особом случае, где Вы чувствуете себя заставленными использовать тот.
Внутренний класс не предлагает конкретных специальных функций в Python. Это - только свойство объекта класса, не отличающегося от целочисленного или свойства строки. Ваш пример OuterClass/InnerClass может быть переписан точно как:
class OuterClass(): pass
class InnerClass(): pass
OuterClass.InnerClass= InnerClass
InnerClass не может знать, был ли он объявлен в другом классе, потому что это - просто простая привязка переменной. Волшебство, которое заставляет связанные методы знать о своем владельце 'сам', не применяется здесь.
innerclass волшебство декоратора в ссылке, которую отправил John, является интересным подходом, но я не использовал бы его как есть. Это не кэширует классы, которые это создает для каждого внешнего объекта, таким образом, Вы получаете новый InnerClass каждый раз, когда Вы называете outerinstance. InnerClass:
>>> o= OuterClass()
>>> i= o.InnerClass()
>>> isinstance(i, o.InnerClass)
False # huh?
>>> o.InnerClass is o.InnerClass
False # oh, whoops...
Также способ, которым это пытается копировать поведение Java предоставления доступа к внешним переменным класса, на внутреннем классе с getattr/setattr, является очень изворотливым, и ненужным действительно (так как больше Pythonic путь должно было бы звонить i. __ внешний __. attr явно).
Если Вы не устанавливаете его сами, я не полагаю, что существует любой способ определить, вкладывается ли класс. Так же так или иначе класс Python не может использоваться как пространство имен (или по крайней мере не легко), я сказал бы, что лучшая вещь сделать просто использовать различные файлы.
Действительно вложенный класс не отличается от любого другого класса - это просто, оказывается, определяется где-то в другом месте, чем пространство имен верхнего уровня (в другом классе вместо этого). Если мы изменяем описание от "вложенного" до "неверхнего уровня", то Вы можете почти достичь достаточно к тому, в чем Вы нуждаетесь.
например:
import inspect
def not_toplevel(cls):
m = inspect.getmodule(cls)
return not (getattr(m, cls.__name__, []) is cls)
Это будет работать на общие падежи, но это не может сделать то, что Вы хотите в ситуациях, где классы переименовываются или иначе управляются после определения. Например:
class C: # not_toplevel(C) = False
class B: pass # not_toplevel(C.B) = True
B=C.B # not_toplevel(B) = True
D=C # D is defined at the top, but...
del C # not_toplevel(D) = True
def getclass(): # not_toplevel(getclass()) = True
class C: pass
Спасибо всем за Ваши ответы.
Я нашел это возможное решение с помощью метаклассов; я сделал это больше для obstination, чем реальная потребность, и это сделано способом, который не будет применим к python 3.
Я хочу совместно использовать это решение так или иначе, таким образом, я отправляю его здесь.
#!/usr/bin/env python
class ScopeInfo(type): # stores scope information
__outers={} # outer classes
def __init__(cls, name, bases, dict):
super(ScopeInfo, cls).__init__(name, bases, dict)
ScopeInfo.__outers[cls] = None
for v in dict.values(): # iterate objects in the class's dictionary
for t in ScopeInfo.__outers:
if (v == t): # is the object an already registered type?
ScopeInfo.__outers[t] = cls
break;
def FullyQualifiedName(cls):
c = ScopeInfo.__outers[cls]
if c is None:
return "%s::%s" % (cls.__module__,cls.__name__)
else:
return "%s.%s" % (c.FullyQualifiedName(),cls.__name__)
__metaclass__ = ScopeInfo
class Outer:
class Inner:
class EvenMoreInner:
pass
print Outer.FullyQualifiedName()
print Outer.Inner.FullyQualifiedName()
print Outer.Inner.EvenMoreInner.FullyQualifiedName()
X = Outer.Inner
del Outer.Inner
print X.FullyQualifiedName()