我只是想简化我的一个类,并引入了一些与flyweight设计模式相同的功能.
但是,我有点困惑,为什么__init__总是被称为__new__.我没想到这个.任何人都可以告诉我为什么会这样,以及我如何能够实现这个功能呢?(除了将实施放入__new__感觉相当hacky之外.)
这是一个例子:
class A(object):
_dict = dict()
def __new__(cls):
if 'key' in A._dict:
print "EXISTS"
return A._dict['key']
else:
print "NEW"
return super(A, cls).__new__(cls)
def __init__(self):
print "INIT"
A._dict['key'] = self
print ""
a1 = A()
a2 = A()
a3 = A()
Run Code Online (Sandbox Code Playgroud)
输出:
NEW
INIT
EXISTS
INIT
EXISTS
INIT
Run Code Online (Sandbox Code Playgroud)
为什么?
我一直在努力学习如何在幕后实现CPython.Python很高级很棒,但我不喜欢把它当成黑盒子.
考虑到这一点,元组是如何实现的?我已经看过了源码(tupleobject.c),但它已经过了我的脑海.
我看到的PyTuple_MAXSAVESIZE = 20和PyTuple_MAXFREELIST = 2000,什么是节约型和"自由列表"?(长度为20/21或2000/2001的元组之间是否存在性能差异?什么强制实现最大元组长度?)
我想获得一些有关在创建类实例时验证参数的 Pythonic 方法的提示。我很难理解 __new__ 方法的正确用法,也许这是它的用法之一?举例来说,我有一个 Test 类,它接受两个参数 a 和 b。例如,如果我想确保两者都必须是整数并且 b 必须大于 a,我可以这样做:
class Test:
def __init__(self, a, b):
if not (isinstance(a,int) and isinstance(b,int)):
raise Exception("bla bla error 1")
if not b > a:
raise Exception("bla bla error 2")
self.a = a
self.b = b
#.....
Run Code Online (Sandbox Code Playgroud)
或者,我可以这样做:
def validate_test_input(a,b):
if not (isinstance(a, int) and isinstance(b, int)):
raise Exception("bla bla error 1")
if not b > a:
raise Exception("bla bla error 2")
class Test:
def __init__(self, a, b):
validate_test_input(a,b)
self.a = …Run Code Online (Sandbox Code Playgroud)