Actually we know super
is used to find the "parent class" and return its object, something like/using self.__class__.__mro__
实际上我们知道super用于查找“父类”并返回其对象,例如/ using self .__ class __.__ mro__
What I was confused about is when to use it exactly?
我很困惑的是什么时候使用它?
Suppose we have a Example model code as below
假设我们有一个示例模型代码,如下所示
version_1
VERSION_1
class Example(models.Model):
name = models.CharField()
age = models.IntegerField()
def save(self, **args, **kwargs):
obj = super(Example, self).save(self, **args, **kwargs)
obj.name = "name changed"
obj.age = "age changed"
return obj
version_2
VERSION_2
class Example(models.Model):
name = models.CharField()
age = models.IntegerField()
def save(self, **args, **kwargs):
self.name = "name changed"
self.age = "age changed"
obj = super(Example, self).save(self, **args, **kwargs)
return obj
so as we can observe above
所以我们可以在上面观察
In version_1 I have called super
first and done modifications to fields and returned the obj
在version_1中,我首先调用super并对字段进行了修改并返回了obj
In version_2 I had modified the fields and after that called super and returned obj
在版本_2中,我修改了字段,之后调用了super并返回了obj
So what happens when super is called before and after modification of fields?
那么在修改字段之前和之后调用super时会发生什么?
Finally what i want to know/confirm is
最后我想知道/确认的是
- Where/why exactly super is used in django forms/models.
- 在django表格/模型中使用/为什么精确超级。
- What is the exact concept of using them in django / python (if I understood this wrong).
- 在django / python中使用它们的确切概念是什么(如果我理解这是错误的)。
3 个解决方案
#1
9
Your Example
class is a subclass of Model
. That means, that Example
inherits all functions from Model
.
您的Example类是Model的子类。这意味着,该示例继承了Model中的所有函数。
Look at the following:
看看以下内容:
class Example():
pass
example = Example()
#let's try to save it
example.save()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Example instance has no attribute 'save'
Now with inheritance.
现在继承。
class Parent():
def save(*args, **kwargs):
print "saving now"
class Example(Parent):
pass
example = Example()
#since Example has no save method, it inherits the Parent's save method.
example.save()
"saving now"
If you override the save() method in your Example class, the Parent's save method will not be called.
如果覆盖Example类中的save()方法,则不会调用Parent的save方法。
class Example(Parent):
def save(self, *args, **kwargs):
print "i know how to save on my own now"
example = Example()
example.save()
"i know how to save on my own now"
If you choose to call super, you are calling the Parent's save function together with your own implementation of save().
如果您选择调用super,则调用Parent的save函数以及您自己的save()实现。
class Example(Parent):
def save(self, *args, **kwargs):
super(Example, self).save(*args, **kwargs)
print "i know how to save on my own now"
example = Example()
example.save()
"saving now" #from parent
"i know how to save on my own" #from example
The same applies to all of djangos classes you inherit from. In fact, the implementation is more complex. You can take a look at the Model definition here on github.
这同样适用于您继承的所有djangos类。实际上,实现更复杂。您可以在github上查看模型定义。
If you feel thrilled, you can dive into the django ORM with this talk
如果您感到兴奋,可以通过此次演讲深入了解django ORM
#2
3
I believe this question in not Django specific, therefore I will try to explain it in a generic way.
我认为这个问题不是特定于Django的,因此我将尝试以通用的方式解释它。
The practicality of super is that you do not need to specify which base class is to be called (this can also be a downside because the mro defines what base class is called).
super的实用性是你不需要指定要调用哪个基类(这也可能是一个缺点,因为mro定义了调用的基类)。
I use super to create mixins (there is an excellent answer on SO that describes what a mixin is). An example that uses super:
我使用super来创建mixins(在SO上有一个很好的答案,描述了mixin是什么)。使用super的示例:
class LemonMixin(object):
def tastes_like(self):
return super(LemonMixin, self).tastes_like() + ' and lemon'
class Cola(object):
def tastes_like(self):
return 'sugar'
class ColaLemon(LemonMixin, Cola):
pass
drink = ColaLemon()
drink.tastes_like() # returns 'sugar and lemon'
The mixin is agnostic of the aplied class so it can use super to use the mro to call a base class.
mixin与aplied类无关,因此可以使用super来使用mro来调用基类。
When to call super is totally up to you. If you, for example, want to check for security you call super after the security checks. If you want to fire an event when something finished, you may want to call super before firing the event. ;-)
什么时候打电话超级完全取决于你。例如,如果您想检查安全性,则在安全检查后调用super。如果您想在某些事情结束时发起事件,您可能需要在触发事件之前调用super。 ;-)
#3
1
You call super
:
你打电话给超级:
- first if the parent's method fills attributes you need in your treatment
- 首先,如果父母的方法填写治疗所需的属性
- last if you change the value of some attributes and want to apply the parent's method treatment with those new values
- 最后,如果您更改某些属性的值,并希望将父方法处理应用于这些新值
In conclusion, when you wanna change the implementation of a parent method:
总之,当您想要更改父方法的实现时:
- Go to the parent's method implementation. Check what is done. Your IDE probably eases the job of retrieving the parent implementation, otherwise go to your Django install directory, then to
/lib/python/site-packages/django
and find the implementation by yourself. - 转到父的方法实现。检查做了什么。您的IDE可能会简化检索父实现的工作,否则请转到Django安装目录,然后转到/ lib / python / site-packages / django并自行查找实现。
- According to your need (=use an attribute generated by the parent method OR change the value of an attribute used by the parent method) use super before OR after your custom code.
- 根据您的需要(=使用父方法生成的属性或更改父方法使用的属性的值)在自定义代码之后使用super。
#1
9
Your Example
class is a subclass of Model
. That means, that Example
inherits all functions from Model
.
您的Example类是Model的子类。这意味着,该示例继承了Model中的所有函数。
Look at the following:
看看以下内容:
class Example():
pass
example = Example()
#let's try to save it
example.save()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: Example instance has no attribute 'save'
Now with inheritance.
现在继承。
class Parent():
def save(*args, **kwargs):
print "saving now"
class Example(Parent):
pass
example = Example()
#since Example has no save method, it inherits the Parent's save method.
example.save()
"saving now"
If you override the save() method in your Example class, the Parent's save method will not be called.
如果覆盖Example类中的save()方法,则不会调用Parent的save方法。
class Example(Parent):
def save(self, *args, **kwargs):
print "i know how to save on my own now"
example = Example()
example.save()
"i know how to save on my own now"
If you choose to call super, you are calling the Parent's save function together with your own implementation of save().
如果您选择调用super,则调用Parent的save函数以及您自己的save()实现。
class Example(Parent):
def save(self, *args, **kwargs):
super(Example, self).save(*args, **kwargs)
print "i know how to save on my own now"
example = Example()
example.save()
"saving now" #from parent
"i know how to save on my own" #from example
The same applies to all of djangos classes you inherit from. In fact, the implementation is more complex. You can take a look at the Model definition here on github.
这同样适用于您继承的所有djangos类。实际上,实现更复杂。您可以在github上查看模型定义。
If you feel thrilled, you can dive into the django ORM with this talk
如果您感到兴奋,可以通过此次演讲深入了解django ORM
#2
3
I believe this question in not Django specific, therefore I will try to explain it in a generic way.
我认为这个问题不是特定于Django的,因此我将尝试以通用的方式解释它。
The practicality of super is that you do not need to specify which base class is to be called (this can also be a downside because the mro defines what base class is called).
super的实用性是你不需要指定要调用哪个基类(这也可能是一个缺点,因为mro定义了调用的基类)。
I use super to create mixins (there is an excellent answer on SO that describes what a mixin is). An example that uses super:
我使用super来创建mixins(在SO上有一个很好的答案,描述了mixin是什么)。使用super的示例:
class LemonMixin(object):
def tastes_like(self):
return super(LemonMixin, self).tastes_like() + ' and lemon'
class Cola(object):
def tastes_like(self):
return 'sugar'
class ColaLemon(LemonMixin, Cola):
pass
drink = ColaLemon()
drink.tastes_like() # returns 'sugar and lemon'
The mixin is agnostic of the aplied class so it can use super to use the mro to call a base class.
mixin与aplied类无关,因此可以使用super来使用mro来调用基类。
When to call super is totally up to you. If you, for example, want to check for security you call super after the security checks. If you want to fire an event when something finished, you may want to call super before firing the event. ;-)
什么时候打电话超级完全取决于你。例如,如果您想检查安全性,则在安全检查后调用super。如果您想在某些事情结束时发起事件,您可能需要在触发事件之前调用super。 ;-)
#3
1
You call super
:
你打电话给超级:
- first if the parent's method fills attributes you need in your treatment
- 首先,如果父母的方法填写治疗所需的属性
- last if you change the value of some attributes and want to apply the parent's method treatment with those new values
- 最后,如果您更改某些属性的值,并希望将父方法处理应用于这些新值
In conclusion, when you wanna change the implementation of a parent method:
总之,当您想要更改父方法的实现时:
- Go to the parent's method implementation. Check what is done. Your IDE probably eases the job of retrieving the parent implementation, otherwise go to your Django install directory, then to
/lib/python/site-packages/django
and find the implementation by yourself. - 转到父的方法实现。检查做了什么。您的IDE可能会简化检索父实现的工作,否则请转到Django安装目录,然后转到/ lib / python / site-packages / django并自行查找实现。
- According to your need (=use an attribute generated by the parent method OR change the value of an attribute used by the parent method) use super before OR after your custom code.
- 根据您的需要(=使用父方法生成的属性或更改父方法使用的属性的值)在自定义代码之后使用super。