SlideShare une entreprise Scribd logo
1  sur  14
Télécharger pour lire hors ligne
How do I...
Use Traits?


October 16, 2009
What are traits?
 Traits provide additional characteristics
 for Python object attributes:
      •   Initialization
      •   Validation
      •   Delegation
      •   Notification
      •   Visualization
What are traits?
 Traits provide additional characteristics
 for Python object attributes:
      •   Initialization
      •   Validation
      •   Delegation
      •   Notification
      •   Visualization
      •   Documentation
Defining Simple Traits
 from enthought.traits.api import HasTraits, Float

 class Rectangle(HasTraits): # <----- Derive from HasTraits
     """ Simple rectangle class with two traits.
     """
     # Width of the rectangle
     width = Float()   # <----- Declare Traits

    # Height of the rectangle
    height = Float() # <----- Declare Traits
Defining Simple Traits
 from enthought.traits.api import HasTraits, Float

 class Rectangle(HasTraits): # <----- Derive from HasTraits
     """ Simple rectangle class with two traits.
     """
     # Width of the rectangle
     width = Float()   # <----- Declare Traits

     # Height of the rectangle
     height = Float() # <----- Declare Traits

 # Demo Code
                                     # Float traits convert integers
 >>> rect = Rectangle()
                                     >>> rect.width = 2
 >>> rect.width
                                     >>> rect.width
 0.0
                                     2.0
 # Set rect width to 1.0
                                     # THIS WILL THROW EXCEPTION
 >>> rect.width = 1.0
                                     >>> rect.width = "1.0"
 1.0
                                     TraitError: The 'width' trait of a
                                     Rectangle instance must be a value
                                     of type 'float', but a value of
                                     '1.0' <type 'str'> was specified.
Default Values
 from enthought.traits.api import HasTraits, Float

 class Rectangle(HasTraits):
     """ Simple rectangle class with two traits.
     """

    # Width of the rectangle
    width = Float(1.0) # <----- Set default to 1.0

    # Height of the rectangle
    height = Float(2.0) # <----- Set default to 2.0




#Demo Code                           # Initialization via
>>> rect = Rectangle()               # keyword arguments
>>> rect.width                       >>> rect = Rectangle(width=2.0,
1.0                                                       height=3.0)
>>> rect.height                      >>> rect.width
2.0                                  2.0
                                     >>> rect.height
                                     3.0
Coercion and Casting
 from enthought.traits.api import HasTraits, Float, CFloat

 class Rectangle(HasTraits):
    """ Simple rectangle class with two traits.
    """

   # Basic traits allow “widening” coersion (Int->Float).
   width = Float()

   # CFloat traits apply float() to any assigned variable.
   height = CFloat() # <----- CFloat is the casting version
                      #        of the basic Float trait


 # Demo Code
 >>> rect = Rectangle()
 >>> rect.height = “2.0” # <----- This Works!
 >>> rect.width = “2.0”
 TraitError: The 'width' trait of a Rectangle instance must be a value
 of type 'float', but a value of '2.0' <type 'str'> was specified.
Traits for Basic Python Types


  Coercing Trait   Casting Trait           Python Type    Default Value
  Bool             CBool           bool                   False
  Complex          CComplex        complex                0+0j
  Float            CFloat          float                  0.0
  Int              CInt            int                    0
  Long             CLong           long                   0L
  Str              CStr            str or unicode         ''
                                   (whichever assigned)
  Unicode          CUnicode        unicode                u''
Traits UI – Default Views
        >>> rect = Rectangle(width=3.0, height = 4.0)
        # Create a UI to edit the traits of the object.
        >>> rect.edit_traits()
Static Trait Notification
 class Amplifier(HasTraits):
       """ Guitar Amplifier Model
       """

       # Volume setting for the amplifier.
       volume = Range(0.0, 11.0, default=5.0)

       # Static observer method called whenever volume is set.
       def _volume_changed(self, old, new):
              if new == 11.0:
                     print “This one goes to eleven”

 # Demo Code
 >>> spinal_tap = Amplifier()
 >>> spinal_tap.volume = 11.0
 This one goes to eleven
 >>> spinal_tap.volume = 11.0 # nothing is printed because
                              # the value didn’t change.
Valid Static Trait Notification Signatures
 def _volume_changed(self):
       # no arguments...

 def _volume_changed(self, new):
       # new -- the just-set value of volume

 def _volume_changed(self, old, new):
       # old -- the previous value of volume
       # new -- the just-set value of volume

 def _volume_changed(self, name, old,   new):
       # name – the name of the trait   (‘volume’)
       # old is the previous value of   volume
       # new is the just-set value of   volume

       # This signature is usually used for the
       # _anytrait_changed() observer that is called
       # whenever any trait is changed on the object.
Dynamic Trait Notification
 class Amplifier(HasTraits):
       """ Guitar Amplifier Model
       """

       # Volume setting for the amplifier.
       volume = Range(0.0, 11.0, default=5.0)


 def printer(value):
       print “new value:”, value

 # Demo Code
 >>> spinal_tap = Amplifier()
 # In the following, name can also be a list of trait names
 >>> spinal_tap.on_trait_change(printer, name=‘volume’)
 >>> spinal_tap.volume = 11.0
 new value: 11.0
Valid Dynamic Trait Notification Signatures
  def observer():
        # no arguments...

  def observer(new):
        # new -- the new value of the changed trait

  def observer(name, new):
        # name -- the name of the changed trait
        # new -- the new value of the changed trait

  def observer(object, name, new):
        # object -- the object containing the changed trait
        # name -- the name of the changed trait
        # new – the new value of the changed trait

  def observer(object, name, old, new):
        # object -- the object containing the changed trait
        # name -- the name of the changed trait
        # old – the previous value of the changed trait
        # new – the new value of the changed trait
EPD
http://www.enthought.com/products/epd.php


Webinars
http://www.enthought.com/training/webinars.php


Enthought Training:
http://www.enthought.com/training/

Contenu connexe

Tendances

Rust-lang
Rust-langRust-lang
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent Seven
Mike Fogus
 

Tendances (20)

Rust-lang
Rust-langRust-lang
Rust-lang
 
Clojure 1.1 And Beyond
Clojure 1.1 And BeyondClojure 1.1 And Beyond
Clojure 1.1 And Beyond
 
Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines Reloaded
 
C++ L01-Variables
C++ L01-VariablesC++ L01-Variables
C++ L01-Variables
 
Programming Language Swift Overview
Programming Language Swift OverviewProgramming Language Swift Overview
Programming Language Swift Overview
 
Swift internals
Swift internalsSwift internals
Swift internals
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
The Magnificent Seven
The Magnificent SevenThe Magnificent Seven
The Magnificent Seven
 
Imugi: Compiler made with Python
Imugi: Compiler made with PythonImugi: Compiler made with Python
Imugi: Compiler made with Python
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby Hackers
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
C++ 11 usage experience
C++ 11 usage experienceC++ 11 usage experience
C++ 11 usage experience
 
Getting started with ES6
Getting started with ES6Getting started with ES6
Getting started with ES6
 
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading2 BytesC++ course_2014_c3_ function basics&parameters and overloading
2 BytesC++ course_2014_c3_ function basics&parameters and overloading
 
Introduction to Rust
Introduction to RustIntroduction to Rust
Introduction to Rust
 
Kotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is comingKotlin Coroutines. Flow is coming
Kotlin Coroutines. Flow is coming
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
Rust言語紹介
Rust言語紹介Rust言語紹介
Rust言語紹介
 
Rustlabs Quick Start
Rustlabs Quick StartRustlabs Quick Start
Rustlabs Quick Start
 
Oops pramming with examples
Oops pramming with examplesOops pramming with examples
Oops pramming with examples
 

Similaire à Scientific Computing with Python Webinar: Traits

Model-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error CheckingModel-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error Checking
Eelco Visser
 
Python workshop intro_string (1)
Python workshop intro_string (1)Python workshop intro_string (1)
Python workshop intro_string (1)
Karamjit Kaur
 
The Kumofs Project and MessagePack-RPC
The Kumofs Project and MessagePack-RPCThe Kumofs Project and MessagePack-RPC
The Kumofs Project and MessagePack-RPC
Sadayuki Furuhashi
 

Similaire à Scientific Computing with Python Webinar: Traits (20)

Python study material
Python study materialPython study material
Python study material
 
C++ process new
C++ process newC++ process new
C++ process new
 
Python course
Python coursePython course
Python course
 
java Basic Programming Needs
java Basic Programming Needsjava Basic Programming Needs
java Basic Programming Needs
 
IronSmalltalk
IronSmalltalkIronSmalltalk
IronSmalltalk
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
 
Advanced Web Technology ass.pdf
Advanced Web Technology ass.pdfAdvanced Web Technology ass.pdf
Advanced Web Technology ass.pdf
 
Model-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error CheckingModel-Driven Software Development - Static Analysis & Error Checking
Model-Driven Software Development - Static Analysis & Error Checking
 
For Beginners - C#
For Beginners - C#For Beginners - C#
For Beginners - C#
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Python workshop intro_string (1)
Python workshop intro_string (1)Python workshop intro_string (1)
Python workshop intro_string (1)
 
Functions in C++ (OOP)
Functions in C++ (OOP)Functions in C++ (OOP)
Functions in C++ (OOP)
 
DSC - Android Study Jams - Session 2
DSC - Android Study Jams - Session 2 DSC - Android Study Jams - Session 2
DSC - Android Study Jams - Session 2
 
The Kumofs Project and MessagePack-RPC
The Kumofs Project and MessagePack-RPCThe Kumofs Project and MessagePack-RPC
The Kumofs Project and MessagePack-RPC
 
Elegant Solutions for Everyday Python Problems Pycon 2018 - Nina Zakharenko
Elegant Solutions for Everyday Python Problems Pycon 2018 - Nina ZakharenkoElegant Solutions for Everyday Python Problems Pycon 2018 - Nina Zakharenko
Elegant Solutions for Everyday Python Problems Pycon 2018 - Nina Zakharenko
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
 
Cocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftCocoa Design Patterns in Swift
Cocoa Design Patterns in Swift
 
C++ nothrow movable types
C++ nothrow movable typesC++ nothrow movable types
C++ nothrow movable types
 
The Ring programming language version 1.8 book - Part 88 of 202
The Ring programming language version 1.8 book - Part 88 of 202The Ring programming language version 1.8 book - Part 88 of 202
The Ring programming language version 1.8 book - Part 88 of 202
 

Plus de Enthought, Inc.

Plus de Enthought, Inc. (14)

Numpy Talk at SIAM
Numpy Talk at SIAMNumpy Talk at SIAM
Numpy Talk at SIAM
 
Talk at NYC Python Meetup Group
Talk at NYC Python Meetup GroupTalk at NYC Python Meetup Group
Talk at NYC Python Meetup Group
 
Scientific Applications with Python
Scientific Applications with PythonScientific Applications with Python
Scientific Applications with Python
 
SciPy 2010 Review
SciPy 2010 ReviewSciPy 2010 Review
SciPy 2010 Review
 
Scientific Computing with Python Webinar March 19: 3D Visualization with Mayavi
Scientific Computing with Python Webinar March 19: 3D Visualization with MayaviScientific Computing with Python Webinar March 19: 3D Visualization with Mayavi
Scientific Computing with Python Webinar March 19: 3D Visualization with Mayavi
 
Chaco Step-by-Step
Chaco Step-by-StepChaco Step-by-Step
Chaco Step-by-Step
 
NumPy/SciPy Statistics
NumPy/SciPy StatisticsNumPy/SciPy Statistics
NumPy/SciPy Statistics
 
February EPD Webinar: How do I...use PiCloud for cloud computing?
February EPD Webinar: How do I...use PiCloud for cloud computing?February EPD Webinar: How do I...use PiCloud for cloud computing?
February EPD Webinar: How do I...use PiCloud for cloud computing?
 
SciPy India 2009
SciPy India 2009SciPy India 2009
SciPy India 2009
 
Parallel Processing with IPython
Parallel Processing with IPythonParallel Processing with IPython
Parallel Processing with IPython
 
Scientific Computing with Python Webinar 9/18/2009:Curve Fitting
Scientific Computing with Python Webinar 9/18/2009:Curve FittingScientific Computing with Python Webinar 9/18/2009:Curve Fitting
Scientific Computing with Python Webinar 9/18/2009:Curve Fitting
 
Scientific Computing with Python Webinar --- August 28, 2009
Scientific Computing with Python Webinar --- August 28, 2009Scientific Computing with Python Webinar --- August 28, 2009
Scientific Computing with Python Webinar --- August 28, 2009
 
Scientific Computing with Python Webinar --- June 19, 2009
Scientific Computing with Python Webinar --- June 19, 2009Scientific Computing with Python Webinar --- June 19, 2009
Scientific Computing with Python Webinar --- June 19, 2009
 
Scientific Computing with Python Webinar --- May 22, 2009
Scientific Computing with Python Webinar --- May 22, 2009Scientific Computing with Python Webinar --- May 22, 2009
Scientific Computing with Python Webinar --- May 22, 2009
 

Dernier

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Dernier (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 

Scientific Computing with Python Webinar: Traits

  • 1. How do I... Use Traits? October 16, 2009
  • 2. What are traits? Traits provide additional characteristics for Python object attributes: • Initialization • Validation • Delegation • Notification • Visualization
  • 3. What are traits? Traits provide additional characteristics for Python object attributes: • Initialization • Validation • Delegation • Notification • Visualization • Documentation
  • 4. Defining Simple Traits from enthought.traits.api import HasTraits, Float class Rectangle(HasTraits): # <----- Derive from HasTraits """ Simple rectangle class with two traits. """ # Width of the rectangle width = Float() # <----- Declare Traits # Height of the rectangle height = Float() # <----- Declare Traits
  • 5. Defining Simple Traits from enthought.traits.api import HasTraits, Float class Rectangle(HasTraits): # <----- Derive from HasTraits """ Simple rectangle class with two traits. """ # Width of the rectangle width = Float() # <----- Declare Traits # Height of the rectangle height = Float() # <----- Declare Traits # Demo Code # Float traits convert integers >>> rect = Rectangle() >>> rect.width = 2 >>> rect.width >>> rect.width 0.0 2.0 # Set rect width to 1.0 # THIS WILL THROW EXCEPTION >>> rect.width = 1.0 >>> rect.width = "1.0" 1.0 TraitError: The 'width' trait of a Rectangle instance must be a value of type 'float', but a value of '1.0' <type 'str'> was specified.
  • 6. Default Values from enthought.traits.api import HasTraits, Float class Rectangle(HasTraits): """ Simple rectangle class with two traits. """ # Width of the rectangle width = Float(1.0) # <----- Set default to 1.0 # Height of the rectangle height = Float(2.0) # <----- Set default to 2.0 #Demo Code # Initialization via >>> rect = Rectangle() # keyword arguments >>> rect.width >>> rect = Rectangle(width=2.0, 1.0 height=3.0) >>> rect.height >>> rect.width 2.0 2.0 >>> rect.height 3.0
  • 7. Coercion and Casting from enthought.traits.api import HasTraits, Float, CFloat class Rectangle(HasTraits): """ Simple rectangle class with two traits. """ # Basic traits allow “widening” coersion (Int->Float). width = Float() # CFloat traits apply float() to any assigned variable. height = CFloat() # <----- CFloat is the casting version # of the basic Float trait # Demo Code >>> rect = Rectangle() >>> rect.height = “2.0” # <----- This Works! >>> rect.width = “2.0” TraitError: The 'width' trait of a Rectangle instance must be a value of type 'float', but a value of '2.0' <type 'str'> was specified.
  • 8. Traits for Basic Python Types Coercing Trait Casting Trait Python Type Default Value Bool CBool bool False Complex CComplex complex 0+0j Float CFloat float 0.0 Int CInt int 0 Long CLong long 0L Str CStr str or unicode '' (whichever assigned) Unicode CUnicode unicode u''
  • 9. Traits UI – Default Views >>> rect = Rectangle(width=3.0, height = 4.0) # Create a UI to edit the traits of the object. >>> rect.edit_traits()
  • 10. Static Trait Notification class Amplifier(HasTraits): """ Guitar Amplifier Model """ # Volume setting for the amplifier. volume = Range(0.0, 11.0, default=5.0) # Static observer method called whenever volume is set. def _volume_changed(self, old, new): if new == 11.0: print “This one goes to eleven” # Demo Code >>> spinal_tap = Amplifier() >>> spinal_tap.volume = 11.0 This one goes to eleven >>> spinal_tap.volume = 11.0 # nothing is printed because # the value didn’t change.
  • 11. Valid Static Trait Notification Signatures def _volume_changed(self): # no arguments... def _volume_changed(self, new): # new -- the just-set value of volume def _volume_changed(self, old, new): # old -- the previous value of volume # new -- the just-set value of volume def _volume_changed(self, name, old, new): # name – the name of the trait (‘volume’) # old is the previous value of volume # new is the just-set value of volume # This signature is usually used for the # _anytrait_changed() observer that is called # whenever any trait is changed on the object.
  • 12. Dynamic Trait Notification class Amplifier(HasTraits): """ Guitar Amplifier Model """ # Volume setting for the amplifier. volume = Range(0.0, 11.0, default=5.0) def printer(value): print “new value:”, value # Demo Code >>> spinal_tap = Amplifier() # In the following, name can also be a list of trait names >>> spinal_tap.on_trait_change(printer, name=‘volume’) >>> spinal_tap.volume = 11.0 new value: 11.0
  • 13. Valid Dynamic Trait Notification Signatures def observer(): # no arguments... def observer(new): # new -- the new value of the changed trait def observer(name, new): # name -- the name of the changed trait # new -- the new value of the changed trait def observer(object, name, new): # object -- the object containing the changed trait # name -- the name of the changed trait # new – the new value of the changed trait def observer(object, name, old, new): # object -- the object containing the changed trait # name -- the name of the changed trait # old – the previous value of the changed trait # new – the new value of the changed trait