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") 的结果为 ...
随机推荐
- systemctl daemon-reload
systemctl daemon-reload: 重新加载某个服务的配置文件,如果新安装了一个服务,归属于 systemctl 管理,要是新服务的服务程序配置文件生效,需重新加载. init 和 sy ...
- c++学习笔记_6
前言:本笔记所对应的课程为中国大学mooc中北京大学的程序设计与算法(三)C++面向对象程序设计,主要供自己复习使用,且本笔记建立在会使用c和java的基础上,只针对与c和java的不同来写 多态 虚 ...
- 【DSP开发】CMD文件
DSP的存储器的地址范围,CMD是主要是根据那个来编的. CMD 它是用来分配rom和ram空间用的,告诉链接程序怎样计算地址和分配空间. 所以不同的芯片就有不同大小的rom和ram.放用户程序的地方 ...
- Bootstrap 控制台示例
1.打开https://getbootstrap.com/docs/4.3/examples/ 2.选择Dashboard 3.右键查看源代码,另存为 4.通过源代码界面下载JS和CSS 5.修改绝对 ...
- [Agc029B]Powers of two_贪心_树形dp
Powers of two 题目链接:https://atcoder.jp/contests/agc029/tasks/agc029_b 数据范围:略. 题解: 可能一点思路都没有. 但是我们发现:如 ...
- ubuntu18上传代码到github
其实在github上建仓库时候就提示你步骤了: 1.注册个github账号并登录 创建一个仓库 https://github.com/ 2.创建SSH Key ssh-keygen -t rsa -C ...
- MS SQL 2012表分区
最近开发一个手机用户统计平台,因为涉及到数据庞大,不得不以一周为单位对统计报表进行分区,所以记录一下,方便以后查看 第一步创建文件分组 对于文件分组共创建了14个,从 xy_group_2014102 ...
- python学习-8 用户有三次机会登陆
用户登陆(三次机会) count = 0 while count < 3: user = input('请输入账号:') pwd = input('请输入密码:') ': print(" ...
- Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)
@Java300 学习总结 一.自定义节点 LinkList底层为双向链表.特点为查询效率低,但增删效率高,线程不安全. 链表数据储存在节点,且每个节点有指向上个和下个节点的指针. 创建ggLinke ...
- LeetCode 答案(python)18-24
18.四个数之和 给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target ...