我正在通过阅读Django源代码来学习编码风格:
在pagination.py Pagination中,源代码定义了一个实例化类Page的私有方法。
def page(self, number):
"""
Returns a Page object for the given 1-based page number.
"""
number = self.validate_number(number)
bottom = (number - 1) * self.per_page
top = bottom + self.per_page
if top + self.orphans >= self.count:
top = self.count
return self._get_page(self.object_list[bottom:top], number, self)
def _get_page(self, *args, **kwargs):
"""
Returns an instance of a single page.
This hook can be used by subclasses to use an alternative to the
standard :cls:`Page` object.
"""
return Page(*args, **kwargs)
如果将方法页面实例化为
,我认为它更具可读性def page(self, number):
"""
Returns a Page object for the given 1-based page number.
"""
number = self.validate_number(number)
bottom = (number - 1) * self.per_page
top = bottom + self.per_page
if top + self.orphans >= self.count:
top = self.count
return Page(self.object_list[bottom:top], number, self)
在额外步骤中定义单独_get_page
方法的优势是什么?
答案 0 :(得分:4)
优点是,就像docstring所说的那样(你也在你的问题中显示):
子类可以使用此挂钩来使用标准的替代方法:cls:
Page
object。
如果我们只想更改Page
课程,我们会覆盖_get_page()
,但不要重复构建top
和bottom
参数的整个逻辑在page()
方法(DRY principle)。
只有当我们想要更改那里计算的逻辑的某些部分时,我们才会覆盖page()
方法。
答案 1 :(得分:4)
它已经在函数的评论中:
<Page.Resources>
<ControlTemplate x:Key="BlurEditFlyout">
....
<ComboBox ItemsSource="{Bind it to the _esaingType}" />
....
<ControlTemplate x:Key="BlurEditFlyout">
</Page.Resources>
<GridView ItemsSource="{x:Bind _items}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:MethodData">
<StackPanel>
....
<Button Visibility="{x:Bind EditButtonVisibility}">
<Button.Flyout>
<Flyout>
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
</Style>
</Flyout.FlyoutPresenterStyle>
<ContentControl Template="{x:Bind FlyoutTemplate}"/>
</Flyout>
</Button.Flyout>
<SymbolIcon Symbol="Edit"/>
</Button>
....
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
想象一下,稍后您编写自己的分页方法(使用更高级的public sealed partial class MainPage : Page
{
ObservableCollection<MethodData> _items = new ObservableCollection<MethodData>();
List<string> _easingType = new List<string>(Enum.GetNames(typeof(EasingType)).ToArray());
Dictionary<MethodName, ControlTemplate> _buttonFlyoutDictionary = new Dictionary<MethodName, ControlTemplate>();
public MainPage()
{
this.InitializeComponent();
LoadFlyoutResources();
_items.Add(GetMethodData(MethodName.Blur));
}
private void LoadFlyoutResources()
{
_buttonFlyoutDictionary.Add(MethodName.Blur, (ControlTemplate)Resources["BlurEditFlyout"]);
.....
}
private MethodData GetMethodData(MethodName methodName)
{
_buttonFlyoutDictionary.TryGetValue(methodName, out ControlTemplate flyoutTemplate);
return new MethodData(methodName, flyoutTemplate);
}
}
public class MethodData
{
public string Name { get; set; }
public ControlTemplate FlyoutTemplate { get; set; }
public Visibility EditButtonVisibility { get; set; }
public MethodData(MethodName name, ControlTemplate flyoutTemplate)
{
Name = name.ToString();
FlyoutTemplate = flyoutTemplate;
EditButtonVisibility = (name == MethodName.Then) ? Visibility.Collapsed : Visibility.Visible;
}
}
public enum MethodName
{
Blur,
....
}
对象),那么您不仅需要使用新的{{1}来修复所有您的代码对象(也许有些人仍然需要使用&#34; 旧&#34;页面对象),但你也必须修补Django代码库的某些部分。
通过引入一个充当def _get_page(self, *args, **kwargs):
"""
Returns an instance of a single page.
This hook can be used by subclasses to use an alternative to the
standard :cls:`Page` object.
"""
return Page(*args, **kwargs)
构造函数的包装器的方法,我们可以猴子补丁构建页面。
例如,我们可以定义自己的speciale Page
类:
Page
然后我们可以将 Page
文件添加到任何应用程序中,并写下:
Page
通常通过创建间接&#34;级别,允许用户在这些间接级别修复某些部分,因此可以将自己的实现注入Django部分。
子类化是最简单的修复,但本身不是唯一的修复。也许您想要预处理某些参数,或者对class SpecialPage(Page):
# ...
pass
对象进行后处理,或者发出一些&#34;信号&#34;对所有与创建的monkey_patching.py
做某事的函数。也许对于一个页面来说,那些不是很符合逻辑的东西,但对于其他对象构造(比如模型实例),添加这些间接层次更有意义。