Python dynamic properties and features

Michael Amin 2021-09-15 08:45:07
python dynamic properties features


learn from 《 smooth python》

1. Use dynamic attributes to transform data

  • stay Python in , Data attribute And processing data Method Generally referred to as the attribute (attribute). Actually , Method is only a callable property
  • We can also create characteristic (property)
from urllib.request import urlopen
import warnings
import os
import json
URL = 'http://www.oreilly.com/pub/sc/osconfeed'
JSON = './osconfeed.json'
def load():
if not os.path.exists(JSON):
msg = 'downloading {} to {}'.format(URL, JSON)
warnings.warn(msg) # Send out a reminder 
with urlopen(URL) as remote, open(JSON, 'wb') as local:
# Use two context managers 
local.write(remote.read())
# Read and save remote files 
with open(JSON) as fp:
return json.load(fp)
feed = load()
print(feed)
print(sorted(feed['Schedule'].keys()))
for key, value in sorted(feed['Schedule'].items()):
print('{:3} {}'.format(len(value), key))
print(feed['Schedule']['speakers'][-1]['serial'])
# This syntax is too long ... How to improve 
from collections import abc
class FrozenJSON:
# A read-only interface , Use attribute notation to access JSON Class object 
def __init__(self, mapping):
self.__data = dict(mapping)
def __getattr__(self, name):
if hasattr(self.__data, name): # There are properties , obtain 
return getattr(self.__data, name)
# call keys And other methods are handled in this way 
else: # No, , structure FrozenJSON
return FrozenJSON.build(self.__data[name])
@classmethod # Alternative construction methods ,@classmethod Decorators are often used like this 
def build(cls, obj):
if isinstance(obj, abc.Mapping):
return cls(obj) # structure FrozenJSON
elif isinstance(obj, abc.MutableSequence):
# It's a sequence , For each element build
return [cls.build(item) for item in obj]
else:
return obj
raw_feed = load()
feed = FrozenJSON(raw_feed)
print(len(feed.Schedule.speakers))
print(sorted(feed.Schedule.keys()))
# ['conferences', 'events', 'speakers', 'venues']
print(feed.Schedule.events[-1].name)
# Why Schools Don't Use Open Source to Teach Programming
p = feed.Schedule.events[-1]
print(type(p))
# <class '__main__.FrozenJSON'>
print(p.name)
# Why Schools Don't Use Open Source to Teach Programming
print(p.speakers)
# [157509]
print(p.age)
# KeyError: 'age'
  • Handle invalid property name , for example Built in keywords , keyword.iskeyword
grad = FrozenJSON({
'name': 'Jim Bo', 'class': 1982})
# print(grad.class) # invalid syntax
print(getattr(grad, 'class')) # 1982

Modify the constructor of the class :

def __init__(self, mapping):
self.__data = {
}
for k,v in mapping.items():
if keyword.iskeyword(k): # If it is a keyword , Add underscore suffix 
k += "_"
self.__data[k] = v
  • Invalid naming ,str.isidentifier()
grad = FrozenJSON({
'2name': 'Jim Bo', 'class': 1982})
print(grad.2name) # SyntaxError: invalid syntax

Change of name

def __init__(self, mapping):
self.__data = {
}
for k,v in mapping.items():
if keyword.iskeyword(k):
k += "_"
if not k.isidentifier(): # Not a legal name , Change it 
k = "_" + k
self.__data[k] = v
print(grad._2name) # Jim Bo
  • __init__ The way is “ Initialization method ”. The real construction method is __new__( But you hardly need to write it yourself )
# Build the pseudo code of the object 
def object_maker(the_class, some_arg):
new_object = the_class.__new__(some_arg) # new Method can also return other class objects 
if isinstance(new_object, the_class):
the_class.__init__(new_object, some_arg)
return new_object
class FrozenJSON:
# A read-only interface , Use attribute notation to access JSON Class object 
def __new__(cls, arg): # The first parameter is the class itself 
if isinstance(arg, abc.Mapping):
return super().__new__(cls)
elif isinstance(arg, abc.MutableSequence):
return [cls(item) for item in arg]
else:
return arg
def __init__(self, mapping):
self.__data = {
}
for k, v in mapping.items():
if keyword.iskeyword(k):
k += "_"
if not k.isidentifier():
k = "_" + k
self.__data[k] = v
def __getattr__(self, name):
if hasattr(self.__data, name): # There are properties , obtain 
return getattr(self.__data, name)
# call keys And other methods are handled in this way 
else: # No, , structure FrozenJSON
return FrozenJSON(self.__data[name])

2. @property

https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208
Please use @property Give me a Screen Object plus width and height attribute , And one. Read-only property resolution

class Screen(object):
def __init__(self):
self._w = 0
self._h = 0
self._r = 786432
@property # Turn the method into an attribute , Call without adding ()
def width(self):
return self._w
@property
def height(self):
return self._h
@width.setter # You can set property values , No, the method is a read-only property 
def width(self, v):
self._w = v
@height.setter
def height(self, v):
self._h = v
@property
def resolution(self):
return self._r
s = Screen()
s.width = 1024
s.height = 768
print('resolution =', s.resolution)
if s.resolution == 786432:
print(' The test passed !')
else:
print(' Test to fail !')
  • The characteristics are Class properties , But the of feature management is Instance attributes The access
class Class:
data = "class data attr"
@property
def prop(self):
return "prop value"
obj = Class()
print(vars(obj)) # {}, vars The function returns obj Of __dict__ attribute 
print(obj.data) # class data attr
obj.data = "changed"
print(vars(obj)) # {'data': 'changed'}
print(Class.data) # class data attr
# The example has been modified data, however Class properties have not been modified 
print(Class.prop) # <property object at 0x0000021A91E4A680>
print(obj.prop) # prop value
# obj.prop = "changed prop" # Report errors can't set attribute
obj.__dict__["prop"] = "changed prop1"
print(vars(obj)) # {'data': 'changed', 'prop': 'changed prop1'}
print(obj.prop) # prop value #
# Read obj.prop The read value method of the feature will still be run . Properties are not masked by instance properties 
Class.prop = "haha" # Cover Class.prop characteristic , Destroy property objects 
print(obj.prop) # changed prop1
# Now? ,obj.prop Get the instance property .
# Class.prop Not a feature , So it won't cover obj.prop.
print(obj.data) # changed
print(Class.data) # class data attr
Class.data = property(lambda self : "data prop value")
# Overwrite... With new features Class.data
print(obj.data) # data prop value
# obj.data By Class.data Characteristics mask 
del Class.data # Delete feature 
print(obj.data) # changed
# Restore as is ,obj.data Get the instance property data

obj.attr Such an expression Can't from obj Start looking for attr, But from obj.__class__ Start , and , Only if No, be known as attr When ,Python Will stay obj Find in examples .

This rule applies not only to features , It also applies to an entire class of descriptors —— Overlay descriptor (overriding descriptor)

2.1 help() file

Use the decorator to create property Object time , Value reading method ( Yes @property Decorator Methods ) The document string as a whole , Become a feature document

>>> class Foo:
@property
def bar(self):
''' documentation '''
return self.__dict__['bar']
@bar.setter
def bar(self, val):
self.__dict__['bar'] = val
>>> help(Foo)
Help on class Foo in module __main__:
class Foo(builtins.object)
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| bar
| documentation
>>> help(Foo.bar)
Help on property:
documentation
  • Classical writing , Pass in doc Parameters
weight = property(get_weight, set_weight, doc='weight in kilograms')

3. Property factory function

In order to reduce writing getter,setter, You can use feature factory functions

def quantity(storage_name):
def qty_getter(instance):
return instance.__dict__[storage_name]
def qty_setter(instance, value):
if value > 0:
instance.__dict__[storage_name] = value
else:
raise ValueError("value must be > 0")
return property(qty_getter, qty_setter)
class LineItem:
weight = quantity('weight') # Use the property factory function to define weight Class properties 
price = quantity('price') # price attribute 
def __init__(self, description, weight, price):
self.description = description
self.weight = weight # Activate properties , Make sure not to be negative and 0
self.price = price
def subtotal(self):
return self.weight * self.price # Use the value stored in the property 
line1 = LineItem("name1", 8, 13.5)
print(line1.weight, line1.price) # 8 13.5
print(sorted(vars(line1).items()))
# [('description', 'name1'), ('price', 13.5), ('weight', 8)]

weight characteristic Cover 了 weight Instance attributes , So right. self.weight or obj.weight Of Each reference consists of Property function processing , Only direct access __dict__ Properties can skip Feature processing logic

4. Property deletion

del operation , Deleting attributes is rare , however python Support this operation

class BlackKnight:
def __init__(self):
self.members = ['an arm',
'another arm',
'a leg',
'another leg']
self.phrases = ["'Tis but a scratch.",
"It's just a flesh wound.",
"I'm invincible!",
"All right, we'll call it a draw."]
@property
def member(self):
print("next member is:")
return self.members[0]
@member.deleter
def member(self):
text = 'BLACK KNIGHT (loses {})\n-- {}'
print(text.format(self.members.pop(0), self.phrases.pop(0)))
knight = BlackKnight()
print(knight.member)
# next member is:
# an arm
del knight.member
# BLACK KNIGHT (loses an arm)
# -- 'Tis but a scratch.
del knight.member
# BLACK KNIGHT (loses another arm)
# -- It's just a flesh wound.
del knight.member
# BLACK KNIGHT (loses a leg)
# -- I'm invincible!
del knight.member
# BLACK KNIGHT (loses another leg)
# -- All right, we'll call it a draw.
del knight.member
# IndexError: pop from empty list
  • Classical writing ,fdel Parameter setting delete function
member = property(member_getter, fdel=member_deleter)
  • If you don't use features , It can also realize low-level special __delattr__ Method treatment Delete attribute The operation of

5. Handle important properties and functions of properties

  • __class__ Reference to the class to which the object belongs ( namely obj.__class__ And type(obj) The action phase of Same as )
    Python Some special methods of , for example __getattr__, Look only in the class of the object , Instead of looking for
  • __dict__ A mapping , Stores the writable properties of an object or class .
    Yes __dict__ Object of property , Anytime Set new properties at will
    If the class has __slots__ attribute , An example of it There may be no __dict__ attribute
  • __slots__
    Class can define this property , Restrict the properties of an instance
    __slots__ attribute The value of is a tuple of strings , Indicates the allowed attributes
    If __slots__ There is no '__dict__', Then the instance of this class does not __dict__ attribute , Instances are only allowed to have properties with the specified name

5.1 Built in functions that handle properties

  • dir([object])
    List most properties of the object ,dir Functions also Not listed Class , for example __mro__、__bases__ and __name__
>>> dir(Foo)
['__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'bar']
  • getattr(object, name[, default])
    from object Get in object name Attribute corresponding to string
    The property obtained may come from The class or superclass to which the object belongs
    If No attribute specified ,getattr function Throw out AttributeError abnormal , Or return default The value of the parameter ( If this parameter is set )
  • hasattr(object, name), Call the function above , See if it returns the same
  • setattr(object, name, value), A new attribute may be created , perhaps Overwrite existing properties
  • vars([object]), return object Object's __dict__ attribute
    If the class to which the instance belongs defines __slots__ attribute , example No, __dict__ attribute , that vars function Can't handle That example

5.2 Special methods for handling properties

  • Use Order number Or built-in getattr、hasattr and setattr function Access properties Metropolis Trigger The corresponding... In the following list Special methods

  • however , direct By way of example __dict__ attribute Reading and writing attribute Not trigger These special methods , This is usually used Skip special methods

  • Special methods It won't be Instance property with the same name cover

版权声明
本文为[Michael Amin]所创,转载请带上原文链接,感谢
https://pythonmana.com/2021/09/20210909141443418n.html

  1. Take you to learn more about nginx basic login authentication: generating passwords using Python
  2. 超硬核Python避坑学习方案奉上!入门到就业一篇就搞定!
  3. Talk about how JMeter executes Python scripts concurrently
  4. Talk about how JMeter executes Python scripts concurrently
  5. Talk about how JMeter executes Python scripts concurrently
  6. python内置函数通过字符串的方式来执行函数代码块,类似java的反射机制相当强大!
  7. python内置函数通过字符串的方式来执行函数代码块,类似java的反射机制相当强大!
  8. python內置函數通過字符串的方式來執行函數代碼塊,類似java的反射機制相當强大!
  9. Les fonctions intégrées Python exécutent des blocs de code de fonction à travers des chaînes, et les mécanismes de réflexion comme Java sont assez puissants!
  10. Python module 1
  11. Python tip: use namedtuple instead of manually created classes
  12. Python - poetry(3)配置项详解
  13. Python - poetry(3)配置项详解
  14. Python - poetry(3)配置項詳解
  15. Python - poetry(3)配置項詳解
  16. Python - détails de l'élément de configuration Poetry (3)
  17. Python - détails de l'élément de configuration Poetry (3)
  18. Python案例实战,pygame模块,Python实现字母代码雨
  19. Python calculation vector angle code
  20. Python基础面试题解读|《Python面试100层》|第1层
  21. 面对小白的pandas命令手册+练习题【三万字详解】
  22. 面對小白的pandas命令手册+練習題【三萬字詳解】
  23. Face au Manuel de commande pandas de Xiaobai + question d'exercice [30 000 mots pour plus de détails]
  24. Interprétation des questions d'entrevue de base Python | 100 couches d'entrevue Python | couche 1
  25. Python data structure and algorithm (17) -- merge sort
  26. Les fonctions intégrées Python exécutent des blocs de code de fonction à travers des chaînes, et les mécanismes de réflexion comme Java sont assez puissants!
  27. Python笔记-uiautomator2截图点击,OpenCV找图
  28. Python文档阅读笔记-OpenCV中Template Matching
  29. Python笔记-利用OpenCV的matchTemplate屏幕找图并使用pyautogui点击
  30. Python筆記-利用OpenCV的matchTemplate屏幕找圖並使用pyautogui點擊
  31. Notes python - utilisez l'écran matchtemplate d'OpenCV pour trouver des images et cliquez sur
  32. Notes de lecture de documents python - Matching de modèles dans OpenCV
  33. Notes python - capture d'écran de l'automate 2 Cliquez pour ouvrir la vue
  34. python链接云服务器的mysql8
  35. python鏈接雲服務器的mysql8
  36. Mysql8 pour les serveurs Cloud liés Python
  37. Python资源大集合,要的话可以拿走!
  38. ️万字【Python基础】保姆式教学️,小白快速入门Python!
  39. ️萬字【Python基礎】保姆式教學️,小白快速入門Python!
  40. Wanzi [base Python] Baby - sitting Teaching, Little White Quick Start Python!
  41. Realizing the function of sending e-mail automatically with Python
  42. Smtpauthenticationerror in Python: solution
  43. 8 steps to teach you how to solve Sudoku in Python! (including source code)
  44. Python change la vie | identifier facilement des centaines de numéros de livraison
  45. Python change life | utilisation de modèles reconnus par ocr
  46. Bibliothèques Python utiles et intéressantes - - psutil
  47. 3. Traitement des données pandas
  48. 【Python编程基础】控制流之链式比较运算符
  49. MFC uses Python scripting language
  50. 【Python編程基礎】控制流之鏈式比較運算符
  51. 【 base de programmation python】 opérateur de comparaison de chaîne pour le flux de contrôle
  52. Python game development, pyGame module, python implementation of Xiaole games
  53. Mise en œuvre du Code de vérification unique (OTP) avec le cadre de repos Django
  54. Python - eval ()
  55. Python - Programmation orientée objet - _Rapport()
  56. Différence entre python - rep (), Str ()
  57. Python - Programmation orientée objet - _Appel()
  58. Python calling matlab script
  59. Python - Programmation orientée objet - _Nouveau() et mode Singleton
  60. Python - Programmation orientée objet - méthode magique (méthode de double soulignement)