Eu tenho uma situação assim ...
class Outer(object):
def some_method(self):
# do something
class Inner(object):
def __init__(self):
self.Outer.some_method() # <-- this is the line in question
Como posso acessar o Outer
método da Inner
classe a partir da classe?
python
scope
nested
inner-classes
T. Stone
fonte
fonte
self.<original_parent_name>
e obter a classe original, não a nova classe da qual são uma subclasse . Espero que as pessoas que estão lendo isso possam visualizar esse cenário difícil e ver o sentido de perguntas como essa.Respostas:
Os métodos de uma classe aninhada não podem acessar diretamente os atributos de instância da classe externa.
Observe que não é necessariamente o caso de existir uma instância da classe externa, mesmo quando você cria uma instância da classe interna.
Na verdade, muitas vezes é recomendado não usar classes aninhadas, uma vez que o aninhamento não implica em nenhum relacionamento particular entre as classes internas e externas.
fonte
Você está tentando acessar a instância da classe de Outer, a partir da instância da classe interna. Portanto, apenas use o método-fábrica para construir a instância Inner e passar a instância Outer para ela.
fonte
talvez eu esteja louco, mas isso parece muito fácil - a questão é fazer sua classe interna dentro de um método da classe externa ...
Além disso ... "self" é usado apenas por convenção, então você pode fazer o seguinte:
Pode-se objetar que você não pode criar essa classe interna de fora da classe externa ... mas isso não é verdade:
então, em algum lugar a quilômetros de distância:
empurre o barco um pouco para fora e estenda esta classe interna (NB para fazer com que super () funcione você tem que mudar a assinatura de classe de mooble para "class mooble (objeto)"
mais tarde
mrh1997 levantou um ponto interessante sobre a herança não comum de classes internas entregues usando essa técnica. Mas parece que a solução é bastante simples:
fonte
Você pretende usar herança, em vez de classes aninhadas como esta? O que você está fazendo não faz muito sentido em Python.
Você pode acessar o
Outer
some_method de apenas referenciandoOuter.some_method
os métodos da classe interna, mas não vai funcionar como você espera. Por exemplo, se você tentar isso:... você obterá um TypeError ao inicializar um
Inner
objeto, porqueOuter.some_method
espera receber umaOuter
instância como seu primeiro argumento. (No exemplo acima, você basicamente está tentando chamarsome_method
como um método de classe deOuter
.)fonte
Você pode acessar facilmente a classe externa usando metaclasse: após a criação da classe externa, verifique seu atributo dict para quaisquer classes (ou aplique qualquer lógica que você precisar - o meu é apenas um exemplo trivial) e defina os valores correspondentes:
Usando essa abordagem, você pode facilmente vincular e referir duas classes entre si.
fonte
Criei algum código Python para usar uma classe externa de sua classe interna , com base em uma boa ideia de outra resposta para esta pergunta. Acho que é curto, simples e fácil de entender.
O código principal, "pronto para produção" (sem comentários, etc.). Lembre-se de substituir todos os valores entre colchetes angulares (por exemplo
<x>
) pelo valor desejado.Explicação de como esse método funciona (as etapas básicas):
Crie uma função chamada
_subclass_container
para atuar como um invólucro para acessar a variávelself
, uma referência à classe de nível superior (do código executado dentro da função).Crie uma variável chamada
_parent_class
que é uma referência à variávelself
desta função, que as subclasses de_subclass_container
podem acessar (evita conflitos de nome com outrasself
variáveis nas subclasses).Retorne a subclasse / subclasse como um dicionário / lista para que o código que chama a
_subclass_container
função possa acessar as subclasses internas.Na
__init__
função dentro da classe de nível superior (ou onde mais necessário), receba as subclasses retornadas da função_subclass_container
na variávelsubclasses
.Atribua subclasses armazenadas na
subclasses
variável a atributos da classe de nível superior.Algumas dicas para tornar os cenários mais fáceis:
Tornando o código para atribuir as subclasses à classe de nível superior mais fácil de copiar e ser usado em classes derivadas da classe de nível superior que têm sua
__init__
função alterada:Insira antes da linha 12 no código principal:
Em seguida, insira nesta função as linhas 5-6 (do código principal) e substitua as linhas 4-7 pelo seguinte código:
Tornar possível a atribuição de subclasses à classe de nível superior quando houver muitas / quantidades desconhecidas de subclasses.
Substitua a linha 6 pelo seguinte código:
Cenário de exemplo de onde esta solução seria útil e onde o nome da classe de nível superior deveria ser impossível de obter:
Uma classe chamada "a" (
class a:
) é criada. Ele tem subclasses que precisam acessá-lo (o pai). Uma subclasse é chamada de "x1". Nesta subclasse, o códigoa.run_func()
é executado.Em seguida, outra classe, denominada "b", é criada, derivada da classe "a" (
class b(a):
). Depois disso, algum código é executadob.x1()
(chamando a subfunção "x1" de b, uma subclasse derivada). Esta função é executadaa.run_func()
, chamando a função "run_func" da classe "a", não a função "run_func" de seu pai, "b" (como deveria), porque a função que foi definida na classe "a" é definida como referência para a função da classe "a", visto que era sua mãe.Isso causaria problemas (por exemplo, se a função
a.run_func
foi excluída) e a única solução sem reescrever o código na classea.x1
seria redefinir a subclassex1
com o código atualizado para todas as classes derivadas da classe "a", o que obviamente seria difícil e não valeria a pena isto.fonte
Eu encontrei isso .
Ajustado para atender à sua pergunta:
Tenho certeza de que você pode escrever um decorador para isso ou algo assim
related: Qual é o propósito das classes internas do python?
fonte
Outra possibilidade:
fonte
Expandindo o pensamento convincente de @ tsnorri, que o método externo pode ser um método estático :
Agora, a linha em questão deve funcionar no momento em que for realmente chamada.
A última linha no código acima fornece à classe Inner um método estático que é um clone do método estático Outer.
Isso tira proveito de dois recursos do Python, que as funções são objetos e o escopo é textual .
... ou classe atual no nosso caso. Portanto, os objetos "locais" para a definição da classe externa (
Inner
esome_static_method
) podem ser referidos diretamente nessa definição.fonte
Alguns anos atrasado para a festa ... mas para expandir a
@mike rodent
resposta maravilhosa de, eu forneci meu próprio exemplo abaixo que mostra o quão flexível é sua solução e por que deveria ser (ou deveria ter sido) aceita responda.Python 3.7
Resultado:
Mais uma vez, uma resposta maravilhosa, adereços para você, microfone!
fonte
É muito simples:
Entrada:
Resultado
classe A func1
classe B func1
fonte
func1
. E, igualmente divertido, você cria umA
dentro do construtor deB
, que NÃO é absolutamente oA
objeto de classe externa daquele particularB
.