• 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的更多相关文章

  1. 一些Python的惯用法和小技巧:Pythonic

    Pythonic其实是个模糊的含义,没有确定的解释.网上也没有过多关于Pythonic的说明,我个人的理解是更加Python,更符合Python的行为习惯.本文主要是说明一些Python的惯用法和小技 ...

  2. python gui之tkinter界面设计pythonic设计

    ui的设计,控件id的记录是一件比较繁琐的事情. 此外,赋值和读取数据也比较繁琐,非常不pythonic. 有没有神马办法优雅一点呢?life is short. 鉴于控件有name属性,通过dir( ...

  3. Be Pythonic ,Google Python Style Guide

    为了更规范的写代码,变得更专业 分号 1 不在句末添加分号,不用分号在一行写两句代码 行长度 2 每行不超过80字符,python会隐式行连接圆括号,中括号,花括号中的字符,如多参数方法调用可以写为多 ...

  4. 为Pythonic论坛添加一个“专题”功能(续)

    上篇博文<为Pythonic论坛添加一个“专题”功能>,在模板的层次上对发帖进行了限制.也就是根据用户是否拥有权限来决定是否显示发帖框. 但是自从这么“投机取巧”的写完模板后,整夜辗转反侧 ...

  5. Python数据模型及Pythonic编程

    Python作为一种多范式语言,它的很多语言特性都能从其他语言上找到参照,但是Python依然形成了一套自己的“Python 风格”(Pythonic).这种Pythonic风格完全体现在 Pytho ...

  6. #13 让代码变得Pythonic

    前言 在学习Python的过程中,肯定听说过这么一个词:Pythonic,它的意思是让你的代码很Python! 一.列表生成式 前面有一节专门讲解了Python的列表,其灵活的使用方法一定让你陶醉其中 ...

  7. Potential Pythonic Pitfalls

    Potential Pythonic Pitfalls Monday, 11 May 2015 Table of Contents Not Knowing the Python Version Obs ...

  8. Python3玩转单链表——逆转单向链表pythonic版

    [本文出自天外归云的博客园] 链表是由节点构成的,一个指针代表一个方向,如果一个构成链表的节点都只包含一个指针,那么这个链表就是单向链表. 单向链表中的节点不光有代表方向的指针变量,也有值变量.所以我 ...

  9. A Pythonic Card Deck: __len__ & __getitem__ & for 循环的嵌套

    1. 列表生成式的嵌套 for 循环: 示例如下: li1 = range(1,6) li2 = list("ABC") # list("ABC") 的结果为 ...

随机推荐

  1. C#中设置自定义控件工具箱图标

    在设计自定义控件时,系统默认生成的图标比较单一难看,如何为控件设计自己的图标呢,这里给出了一种基于ToolBoxBitmap 属性设置自定义控件工具箱图标的方法. 1)首先将图标文件名改为自定义控件名 ...

  2. 编写expect程序报extra characters after close-brace错误或extra characters after close-quote,解决

    expect程序报extra characters after close-brace或extra characters after close-quote 可能原因 流程控制语句中的"{& ...

  3. javascript一些实用的方法

    判断数据类型 function isType(type) { return function(obj) { return {}.toString.call(obj) == "[object ...

  4. 记一次 vmware ESXI 升级

    旧服务器的esxi版本为 60(6765062),计划安装成为最新版 的为ESXI 60  (14513180),中间波折遇坑多次,现记录如下: 一.开启ESXI的SSH 访问权限(可以通过按F2进入 ...

  5. linux用户管理添加用户的默认配置文件useradd详解

    /etc/default/useradd 文件 cat /etc/default/useradd 常用命令: useradd  添加用户 userdel   删除用户 passwd   改密码 use ...

  6. Oracle 10g 归档日志满了的解决办法

    如果Oracle的归档日志满了,应用连接数据库就会出错,这时需要手工删除过期的归档日志,方法如下: 1.指定数据库实例 $ export ORACLE_SID=db1 2.进入rman $ rman ...

  7. Win7 Eclipse 搭建spark java1.8编译环境,JavaRDD的helloworld例子

    [学习笔记] Win7 Eclipse 搭建spark java1.8编译环境,JavaRDD的helloworld例子: 在eclipse oxygen上创建一个普通的java项目,然后把spark ...

  8. MVVM模式中ViewModel和View、Model有什么区别

    Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就是展现出来的用户界面. 基本上,绝大多数软件所做的工作无非就是从数据 ...

  9. java源码--Vector和Stack

    一.Vector简介 1.1.Vector概述 通过API中可以知道: 1)Vector是一个可变化长度的数组 2)Vector增加长度通过的是capacity和capacityIncrement这两 ...

  10. IT学习的计算机网络内容

    1.一种结构:数据结构 参考书目:<大话数据结构>.<数据结构(C#语言描述)>.<剑指Offer> ①线性表部分: 线性表(上){ 数组.ArrayList } ...