9. A Pythonic Object
- Thanks to the Python data model, your user-defined types can behave as naturally as the built-in types. And this can be accomplished without inheritance, in the spirit of duck typing: you just implement the methods needed for your objects to behave as expected.
1. Classmethod Versus Staticmethod
class Test:
@staticmethod
def f1(*args):
print args
# define a method that operates on the class and not on instances.
@classmethod
def f2(*args): # cls = args[0]
print args t = Test()
t.f1('1') # ('1',)
t.f2('1') # (<class __main__.Test at 0x10afeca78>, '1') # 1. Classmethod's most common use is for alternative constructors.
# 2. In essence, a static method is just like a plain function that
# happens to live in a class body, instead of being defined at the
# module level.
2. Formatted Displays
brl = 1/2.43
print(brl) # 0.4115226337448559
print(format(brl, '0.4f')) # 0.4115
print('BRL = {rate:0.2f}'.format(rate=brl)) # BRL = 0.41
print(format(42, 'b')) # 101010
print(format(2/3, '.1%')) # 66.7%
from datetime import datetime
now = datetime.now()
print("It's {:%I:%M %p}".format(now)) # It's 10:59 AM class A:
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __iter__(self):
return (i for i in (self.a1, self.a2))
def __format__(self, fmt_spec=''):
if fmt_spec is '':
fmt_spec = '({}, {})'
return fmt_spec.format(*self) a = A(3, 4)
print(format(a)) # (3, 4)
print(format(a, '-->{}, {}<--')) # -->3, 4<-- # 1. A format string such as '{0.mass: 5.3e}' actually uses two
# separate notations. The '0.mass' to the left of the colon is the
# field_name part of the replacement field syntax; the '5.3e' after
# the colon is the formatting specifier.
# 2. A few built-in types have their own presentation codes.
# 3. If a class has no __format__, format(obj) returns str(obj)
3. Private and “Protected” Attributes in Python
- Python stores the attributes with two leading underscores in the instance __dict__, prefixed with a leading underscore and the class name. (Dog + __mood --> _Dog__mood)
- Name mangling is about safety, not security: it’s designed to prevent accidental access and not intentional wrongdoing.
- But if you are doing 'v1._Vector__x = 7' in production code, you can’t complain if something blows up.
- Attributes with a single _ prefix are called “protected” in some corners of the Python documentation.9 The practice of “protecting” attributes by convention with the form self._x is widespread, but calling that a “protected” attribute is not so common. Some even call that a “private” attribute.
4. Object Representations
from array import array
import math class Vector2d:
typecode = 'd'
def __init__(self, x, y):
self.__x = float(x)
self.__y = float(y)
@property
def x(self):
return self.__x
@property
def y(self):
return self.__y
def __iter__(self):
return (i for i in (self.x, self.y)) # iterator
# yield self.x; yield.self.y
def __repr__(self): # for developer
class_name = type(self).__name__ # safer to inherit
return '{}({!r}, {!r})'.format(class_name, *self) # iterable
def __str__(self): # for user
return str(tuple(self))
def __bytes__(self):
return (bytes([ord(self.typecode)]) + bytes(array(self.typecode, self)))
def __eq__(self, other):
# It works for Vector2d operands but also returns True when comparing
# Vector2d instances to other iterables holding the same numeric values
# (e.g., Vector(3, 4) == [3, 4]).
return tuple(self) == tuple(other)
def __abs__(self):
return math.hypot(self.x, self.y)
def __bool__(self):
return bool(abs(self))
@classmethod
def frombytes(cls, octets):
# Read the typecode from the first byte.
typecode = chr(octets[0])
# Create a memoryview from the octets and use the typecode to cast it.
memv = memoryview(octets[1:]).cast(typecode)
# print(memv) # <memory at 0x1012fb108>
# print(*memv) # 3.0 4.0
return cls(*memv)
def __format__(self, fmt_spec=''):
if fmt_spec.endswith('p'):
fmt_spec = fmt_spec[:-1]
outer_fmt = '<{}, {}>'
else:
outer_fmt = '({}, {})'
components = (format(c, fmt_spec) for c in self)
return outer_fmt.format(*components)
def __hash__(self):
return hash(self.x) ^ hash(self.y) v1 = Vector2d(3, 4)
print(v1.x) # 3.0
# v1.x = 5 # AttributeError: can't set attribute
a, b = v1 # __iter__
print(a, b) # 3.0 4.0
print(repr(v1)) # Vector2d(3.0, 4.0)
print(v1) # (3.0, 4.0) __str__
print(bytes(v1)) # b'd\x00\x00\x00\x00\x00\x00\x08@\x00\x00\x00\x00\x00\x00\x10@'
print(v1 == eval(repr(v1))) # True __eq__
print(abs(v1)) # 5.0
print(bool(v1)) # True
print(bool(Vector2d(0, 0))) # False
v2 = Vector2d.frombytes(bytes(v1))
print(v1 == v2) # True
print(format(v1)) # (3.0, 4.0)
print(format(v1, '.3f')) # (3.000, 4.000)
print(format(v1, '.2ep')) # <3.00e+00, 4.00e+00>
print(hash(v1)) # 7 # 1. In Python 3, __repr__, __str__, and __format__ must always return
# Unicode strings (type str). Only __bytes__ is supposed to return a
# byte sequence (type bytes).
# 2. We can implement the __hash__ method. It should return an int and
# ideally take into account the hashes of the object attributes that
# are also used in the __eq__ method, because objects that compare equal
# should have the same hash. The __hash__ special method documentation
# suggests using the bitwise XOR operator (^) to mix the hashes of the
# components.
# 3. It’s not strictly necessary to implement properties or otherwise
# protect the instance attributes to create a hashable type.
# Implementing __hash__ and __eq__ correctly is all it takes. But the
# hash value of an instance is never supposed to change.
5. Saving Space with the __slots__ Class Attribute
P264
6. Overriding Class Attributes
- Class attributes can be used as default values for instance attributes.
- Class attributes are public, they are inherited by subclasses, so it’s common practice to subclass just to customize a class data attribute.
9. A Pythonic Object的更多相关文章
- 一些Python的惯用法和小技巧:Pythonic
Pythonic其实是个模糊的含义,没有确定的解释.网上也没有过多关于Pythonic的说明,我个人的理解是更加Python,更符合Python的行为习惯.本文主要是说明一些Python的惯用法和小技 ...
- python gui之tkinter界面设计pythonic设计
ui的设计,控件id的记录是一件比较繁琐的事情. 此外,赋值和读取数据也比较繁琐,非常不pythonic. 有没有神马办法优雅一点呢?life is short. 鉴于控件有name属性,通过dir( ...
- Be Pythonic ,Google Python Style Guide
为了更规范的写代码,变得更专业 分号 1 不在句末添加分号,不用分号在一行写两句代码 行长度 2 每行不超过80字符,python会隐式行连接圆括号,中括号,花括号中的字符,如多参数方法调用可以写为多 ...
- 为Pythonic论坛添加一个“专题”功能(续)
上篇博文<为Pythonic论坛添加一个“专题”功能>,在模板的层次上对发帖进行了限制.也就是根据用户是否拥有权限来决定是否显示发帖框. 但是自从这么“投机取巧”的写完模板后,整夜辗转反侧 ...
- Python数据模型及Pythonic编程
Python作为一种多范式语言,它的很多语言特性都能从其他语言上找到参照,但是Python依然形成了一套自己的“Python 风格”(Pythonic).这种Pythonic风格完全体现在 Pytho ...
- #13 让代码变得Pythonic
前言 在学习Python的过程中,肯定听说过这么一个词:Pythonic,它的意思是让你的代码很Python! 一.列表生成式 前面有一节专门讲解了Python的列表,其灵活的使用方法一定让你陶醉其中 ...
- Potential Pythonic Pitfalls
Potential Pythonic Pitfalls Monday, 11 May 2015 Table of Contents Not Knowing the Python Version Obs ...
- Python3玩转单链表——逆转单向链表pythonic版
[本文出自天外归云的博客园] 链表是由节点构成的,一个指针代表一个方向,如果一个构成链表的节点都只包含一个指针,那么这个链表就是单向链表. 单向链表中的节点不光有代表方向的指针变量,也有值变量.所以我 ...
- A Pythonic Card Deck: __len__ & __getitem__ & for 循环的嵌套
1. 列表生成式的嵌套 for 循环: 示例如下: li1 = range(1,6) li2 = list("ABC") # list("ABC") 的结果为 ...
随机推荐
- mybatis问题。foreach循环遍历数组报错情况,及其解决方法
根据条件查询数据列表,mybatis查询代码如下 如果只查询属于特定部门拥有的数据权限.这需要用 String[ ] codes保存当前部门及其子部门的部门编码. 所以需要在mybatis中遍历编码数 ...
- Python3 Selenium自动化web测试 ==> 第十一节 WebDriver高级应用 -- 显示等待 + 二次封装
学习目的: 掌握显示等待 掌握二次封装 正式步骤: step1:显示等待的代码示例 # -*- coding:utf-8 -*- from selenium import webdriver from ...
- 【Fiori系列】浅谈SAP Fiori的设计美感与发展历程
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[Fiori系列]浅谈SAP Fiori的设计美 ...
- ubuntu下删除带锁文件夹
1.终端下,cd 到要删带锁文件夹所在目录 2.输入 + 带锁文件夹名称 输入用户密码,解锁成功 3.现在该文件可以进行移动或者删除
- 【VS开发】IPicture在指定窗口绘制图
1.利用IPicture接口加载.显示图片 IPicture接口管理一个图片对象和它的属性.图片对象提供对Bitmap Icon Metafile的语言不相关的抽象支持.图像对象的主要接口是IPict ...
- 最新 搜狐java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.搜狐等10家互联网公司的校招Offer,因为某些自身原因最终选择了搜狐.6.7月主要是做系统复习.项目复盘.LeetCode ...
- STM32 MCU一次计算优化和提速
1.背景 STM32 MCU对25.6Kb数据进行压缩,丢掉每个数据的低4位然后2个字节拼接为1个字节.发现处理耗时竞达1ms以上,于是开始进行优化,最后达到200us的效果,提速5倍以上. 2.优化 ...
- PTA(Advanced Level)1041.Be Unique
Being unique is so important to people on Mars that even their lottery is designed in a unique way. ...
- 题目13 在O(1)时间删除链表节点
///////////////////////////////////////////////////////////////////////////////////// // 3. 题目13 在O( ...
- 剑指offer16:输入两个单调递增的链表,合成后的链表满足单调不减规则。
1 题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 2 思路与方法 迭代法:两个链表中较小的头结点作为合并后头结点,之后依次合并两个链表中较小的 ...