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") 的结果为 ...
随机推荐
- Bootstrap, 模态框实现值传递,自动勾选
目录 Bootstrap,模态框自动勾选,值传递 1.父页面 2. 子页面(modal) 模态框 Bootstrap,模态框自动勾选,值传递 场景: 有一个这样的需求, 在父页面有一个table, ...
- Linux生成ssh密钥免密登录,允许/禁止密码登录,允许/禁止root远程登录,更改ssh端口
进入想要使用密钥登录的用户家目录 cd 或 cd ~ 执行密钥创建命令,不行可能需要下载openssh-server与openssh-client ssh-keygen -t rsa -P " ...
- MATLAB符号求解极限积分微分级数2
一.符号表达式的极限 limit(F,x,a):求当时,符号表达式F的极限. limit(F,a):符号表达式F采用默认自变量(可由函数findsym求得),该函数求F的自变量趋于a时的极限值. li ...
- idea配置git的步骤
第一次git到GitHub过程 打开到项目 这样就不用再用git Bash敲命令了
- Java核心1(第三章)
3.6字符串 子串substring(a,b)方法 第二个参数是不想复制的第一个位置 可以从一个较大的字符串中提取一个子串 3.6.2拼接 Java允许使用+号链接两个字符串 3.6.3不可 ...
- [CF306C]White, Black and White Again_排列组合
White, Black and White Again 题目链接:https://www.luogu.org/problem/CF306C 数据范围:略. 题解: 记得不要看错题,容易看成来回交替下 ...
- [转帖]Docker 更新版本 以及 data-root
Docker 更新版本 https://www.cnblogs.com/operationhome/archive/2019/08/11/11322150.html 园友说 docker 使用了 da ...
- 【转帖】lmbench的简单使用
https://www.cnblogs.com/mutong1228/p/10485840.html 下载地址 http://www.bitmover.com/lmbench/ tar -zxvf l ...
- c c++各种类型的取值范围
int类型的变量存储值从-2147483648到2147483647 //例子 #include <iostream> using namespace std; int main(void ...
- webpack打包时删除console.log,和debugger
开发过程中我们不可避免的需要console.log调试,然而在上线时如果不删除这些console.log可能会造成内存泄漏,因为console.log出来的变量是不会被GC的,webpack给我们提供 ...