Найти - Пользователи
Полная версия: super() вопрос [python3]
Начало » Python для экспертов » super() вопрос [python3]
1
KULINAR847
 class A:
	def __new__(cls, *args):							
		if (len(args) == 0):
			return super(A, cls).__new__(cls)
		
		if int(args[0]) < 5:
			return super(A, cls).__new__(cls)
		else:
			return 0
	def __init__(self, n):
		n = n + 1
		print('a ' + str(n))
		B(n)
	
class B(A):
	def __new__(cls, *args):							
		return super(B, cls).__new__(cls)
	
	def __init__(self, n):
		n = n + 1
		print('b ' + str(n))
		try:
			# Почему если раскомментировать строку ниже код выполняется - b 6
			#A(n)
			# А если раскомментировать строку ниже то ошибка ? - b 664error 
			#super().__init__(n)
		except:
			print('error')
a = A(0)
PEHDOM
KULINAR847
# А если раскомментировать строку ниже то ошибка ? - b 664error #super().__init__(n)
а какой результат вы ожидаете? у вас тут бесконечная рекурсия , рано или поздно вы получите maximum recursion depth exceeded.
когда вы делаете super().__init__(n) то вы вызываетет метод __init__ родителя для инстанса класса В(потомка), а когда делаете A(n) то создаете новый инстанс класса А.
Соотвевенно в классе В вы не передаете конструктору(алокатору?) __new__ никаких аргументов :
 return super(B, cls).__new__(cls)

поэтому в А.__new__ счетчик-ограничитель не срабатывает, а срабатывает вто это
 if (len(args) == 0):
			return super(A, cls).__new__(cls)
вот оно вам и колбасит код до бесконечности, а когда вы далаете A(n) то А.__new__ вы вызываете с аргументом и срабатывает код:
 if int(args[0]) < 5:
			return super(A, cls).__new__(cls)
		else:
			return 0
и рекурсия прерывается.
Надеюсь понятно объяснил.
чтобы ограничитель срабатывал нужно вызывать конструктор класса А с соответствующими аргументами:
 return super(B, cls).__new__(cls, *args)
KULINAR847
PEHDOM
Уважаемый PEHDOM благодарю за объяснение. Теперь я понял, что даже если заменить
 super().__init__(n)
на
 A.__init__(self,n)
результат будет тот же. Хотелось завершить как-нибудь рекурсию через super()
PEHDOM
KULINAR847
Хотелось завершить как-нибудь рекурсию через super()
нужно менять логику или в А.__new__ или в B.__new__ (выше я уже писал как), или в А.__init__ ставить доп проверку типа
 if n < 5:
    B(n)
или делать это же в B.__init__ типа такой:
  if n <5:
    super().__init__(n)
потому что проверка у вас идет не в __init__ а в __new__, а __new__ вызываеться только при создании нового инстанса ,а когда вы дергаете супером метод __init__ родителя вызываеться только __init__ родителя, __new__ родителя не вызываеться.
KULINAR847
PEHDOM
Точно
AD0DE412
поправте если ошибаюсь super().__init__(n) в классе В дергает только метод из класа А без создания энкземпляра класса А
PEHDOM
AD0DE412
super().__init__(n) в классе В дергает только метод из класа А без создания энкземпляра класса А
естественно, super().__init__(n) в данном конкретном сдучае можно записать как A.__init__(self, n). оно просто выполняет метод класса А над инстансом дочернего класса В. экземпляр класса А не создаеться при этом.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB