• 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. 13 Ways Companies Do Whatsapp Marketing & Support (May 2019)

    13 Ways Companies Do Whatsapp Marketing & Support (May 2019) By Iaroslav Kudritskiy  We're livin ...

  2. 蓝牙AT模式

      一.蓝牙AT模式设置方式 在通电前按住蓝牙模块黑色按钮,接电,当蓝牙指示灯按每隔两秒闪烁一次时进入AT模式: 有3种设置方式: 1.默认设置 模块工作角色:从模式    串口参数:38400bit ...

  3. Windows下遍历所有GIT目录更新项目脚本

    将下面代码保存为.bat文件 @echo off set cdir=%~dp0 for /f "delims=" %%i in ('dir /ad/b/s "%cdir% ...

  4. 【AMAD】django-channels -- 为Django带来异步开发

    动机 简介 个人评分 动机 目前web生态的发展带来了很多异步特性,比如websocket.而原生Django并不支持. 简介 django-channels1为Django带来了Websocket, ...

  5. ue-cli3 取消eslint校验代码

    参考链接:https://www.cnblogs.com/sjie/p/9884362.html

  6. springboot datajpa 简明说明

    findById返回Optional的使用 查询 public Object lookupDevice(Integer id) { return deviceJpa.findById(id).orEl ...

  7. Docker 安装 Tomcat

    查找Docker Hub上的tomcat镜像 docker search tomcat 取官方的镜像 docker pull tomcat 使用tomcat镜像 创建目录tomcat,用于存放后面的相 ...

  8. 正确理解使用Vue里的nextTick方法

    最近,在项目中要使用Swiper做一个移动端轮播插件.需要先异步动态加载数据后,然后使用v-for渲染节点,再执行插件的滑动轮播行为.解决这个问题,我们通过在组件中使用vm.$nextTick来解决这 ...

  9. 1.3.3 并发容器类MAP/LIST/SET/QUEUE

    HashMap 下标计算方法:hashCode & (length-1) ,&按位与操作,二进制相同位都是1,该位才为1 JDK1.7与JDK1.8中HashMap区别: JDK1.8 ...

  10. SSM+pagehelper分页

    1.maven依赖 <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId> ...