В чем разница между старым и новым стилем классов в Python?

Вы можете посмотреть PostSharp . Они даже имеют образец в Связывании данных . Код, взятый оттуда:

/// 
/// Aspect that, when apply on a class, fully implements the interface 
///  into that class, and overrides all properties to
/// that they raise the event .
/// 
[Serializable]
[IntroduceInterface( typeof(INotifyPropertyChanged), 
                     OverrideAction = InterfaceOverrideAction.Ignore )]
[MulticastAttributeUsage( MulticastTargets.Class, 
                          Inheritance = MulticastInheritance.Strict )]
public sealed class NotifyPropertyChangedAttribute : InstanceLevelAspect, 
                                                     INotifyPropertyChanged
{

    /// 
    /// Field bound at runtime to a delegate of the method OnPropertyChanged.
    /// 
    [ImportMember( "OnPropertyChanged", IsRequired = false)] 
    public Action OnPropertyChangedMethod;

    /// 
    /// Method introduced in the target type (unless it is already present);
    /// raises the  event.
    /// 
    /// Name of the property.
    [IntroduceMember( Visibility = Visibility.Family, IsVirtual = true, 
                      OverrideAction = MemberOverrideAction.Ignore )]
    public void OnPropertyChanged( string propertyName )
    {
        if ( this.PropertyChanged != null )
        {
           this.PropertyChanged( this.Instance, 
                                  new PropertyChangedEventArgs( propertyName ) );
        }
    }

    /// 
    /// Event introduced in the target type (unless it is already present);
    /// raised whenever a property has changed.
    /// 
    [IntroduceMember( OverrideAction = MemberOverrideAction.Ignore )]
    public event PropertyChangedEventHandler PropertyChanged;

    /// 
    /// Method intercepting any call to a property setter.
    /// 
    /// Aspect arguments.
    [OnLocationSetValueAdvice, 
     MulticastPointcut( Targets = MulticastTargets.Property, 
         Attributes = MulticastAttributes.Instance)]
    public void OnPropertySet( LocationInterceptionArgs args )
    {
        // Don't go further if the new value is equal to the old one.
        // (Possibly use object.Equals here).
        if ( args.Value == args.GetCurrentValue() ) return;

        // Actually sets the value.
        args.ProceedSetValue();

        // Invoke method OnPropertyChanged (our, the base one, or the overridden one).
        this.OnPropertyChangedMethod.Invoke( args.Location.Name );

    }
}

Использование так же просто:

[NotifyPropertyChanged]
public class Shape
{
   public double X { get; set; }
   public double Y { get; set; }
}

Примеры, взятые с сайта PostSharp и вставленные для завершения ответа

921
задан Pikachu the Parenthesis Wizard 29 October 2018 в 14:02
поделиться

4 ответа

От http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes :

До Python 2.1, классы старого стиля были единственным ароматом, доступным пользователю.

понятие класса (старого стиля) не связано с понятием типа: если x экземпляр класса старого стиля, то x.__class__ определяет класс x, но type(x) всегда <type 'instance'>.

Это отражает то, что все экземпляры старого стиля, независимо от их класса, реализованы с единственным встроенным типом, названным экземпляром.

Модернизированные классы были представлены в Python 2.2 для объединения понятия класса и типа . Модернизированный класс является просто пользовательским типом, ни больше, ни меньше.

, Если x является экземпляром модернизированного класса, то type(x) обычно то же как x.__class__ (хотя этому не гарантируют †“модернизированный экземпляр класса, разрешен переопределить значение, возвращенное для x.__class__).

главная мотивация для представления модернизированных классов должна предоставить объединенной объектной модели полную метамодель .

Это также обладает многими непосредственными преимуществами, как способность разделить на подклассы большинство встроенных типов или введение "дескрипторов", которые включают вычисленные свойства.

По причинам совместимости, классы все еще старого стиля значением по умолчанию .

Модернизированные классы создаются путем определения другого модернизированного класса (т.е. тип) как родительский класс или "тип верхнего уровня" объект, если никакой другой родитель не необходим.

поведение модернизированных классов отличается от того из классов старого стиля во многих важных деталях в дополнение к тому, что возвращает тип.

Некоторые из этих изменений фундаментальны для новой объектной модели, как способ, которым вызываются специальные методы. Другие являются "мерами", которые не могли быть реализованы прежде для проблем совместимости, как порядок разрешения метода в случае множественного наследования.

Python 3 только имеет модернизированные классы .

, Неважно, если Вы разделяете на подклассы от object или нет, классы являются новым стилем в Python 3.

521
ответ дан 9 revs, 6 users 56% 29 October 2018 в 14:02
поделиться

Модернизированные классы наследовались от object и должны быть записаны как таковой в Python 2.2 вперед (т.е. class Classname(object): вместо class Classname:). Базовое изменение должно объединить типы и классы, и хороший побочный эффект этого состоит в том, что оно позволяет Вам наследоваться встроенным типам.

Read descrintro для получения дополнительной информации.

7
ответ дан Francesco Montesano 29 October 2018 в 14:02
поделиться

По объявлению:

Классы нового стиля наследуются от объекта или от другого класса нового стиля.

class NewStyleClass(object):
    pass

class AnotherNewStyleClass(NewStyleClass):
    pass

Классы старого стиля не наследуются.

class OldStyleClass():
    pass

Примечание Python 3 :

Python 3 не поддерживает классы старого стиля, поэтому любая из указанных выше форм приводит к классу нового стиля.

299
ответ дан 19 December 2019 в 20:21
поделиться

Классы старого стиля все еще немного быстрее для поиска атрибутов. Обычно это не важно, но может быть полезно в чувствительном к производительности коде Python 2.x:

In [3]: class A:
   ...:     def __init__(self):
   ...:         self.a = 'hi there'
   ...: 

In [4]: class B(object):
   ...:     def __init__(self):
   ...:         self.a = 'hi there'
   ...: 

In [6]: aobj = A()
In [7]: bobj = B()

In [8]: %timeit aobj.a
10000000 loops, best of 3: 78.7 ns per loop

In [10]: %timeit bobj.a
10000000 loops, best of 3: 86.9 ns per loop
40
ответ дан 19 December 2019 в 20:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: