在python中,所有数据都是对象,任何对象都应该有属性和方法。有人知道没有任何属性和方法的python对象吗?
>>> len(dir(1))
64
这很容易通过覆盖__dir__
and来实现__getattribute__
:
class Empty(object):
def __dir__(self):
return []
def __getattribute__(self, name):
raise AttributeError("'{0}' object has no attribute '{1}'".format(type(self).__name__, name))
e = Empty()
dir(e)
[]
e.__name__
AttributeError: 'Empty' object has no attribute '__name__'
(在python2中,Empty
需要是新式类,所以class Empty(object):
是必需的;在python3中,旧式类已经灭绝,所以class Empty:
就足够了。)
是的!(或者没有...)
def AMeta(name, bases, dct):
class NoProp:
pass
del NoProp.__doc__
del NoProp.__module__
return NoProp
class A:
__metaclass__ = AMeta
print dir(A), 'len', len(dir(A))
print
print 'but... A.__name__ is', A.__name__
print 'Delete it!'
try:
del A.__name__
except Exception as e:
print 'Did not work: ', repr(e)
print
print 'and... A.__dict__ is', A.__dict__
print 'Delete it!'
try:
del A.__dict__
except Exception as e:
print 'Did not work: ', repr(e)
print
print 'and... A.__bases__ is', A.__bases__
print 'Delete it!'
try:
del A.__bases__
except Exception as e:
print 'Did not work: ', repr(e)
print
print 'What is the type of A?'
t = type(A)
print t, 'which is a', type(t)
print "All of these will raise an AttributeError:"
print "A.__class__, A.__module__, (and maybe some others which are usually there too...)"
通常,所有对象都有一些属性,无论这些属性是什么。但是当使用元类时,您可以自定义创建类的方式,然后就可以了。
但是,即使dir
为空,您仍然可以访问A.__name__
, A.__dict__
, A.__bases__
.
这就是我所做的测试给我的:
[] len 0
but... A.__name__ is NoProp
Delete it!
Did not work: TypeError('__name__ must be a string object',)
and... A.__dict__ is {}
Delete it!
Did not work: TypeError('__dict__ must be a dictionary object',)
and... A.__bases__ is ()
Delete it!
Did not work: TypeError('__bases__ must be a tuple object',)
What is the type of A?
<type 'classobj'> which is a <type 'type'>
All of these will raise an AttributeError:
A.__class__, A.__module__, (and maybe some others which are usually there too...)
没有遇到任何这样的对象,它没有任何属性..见下文
In [74]: class dummy():
....: pass
....:
In [75]: d1 = dummy()
In [76]: dir(d1)
Out[76]: ['__doc__', '__module__']
In [77]: len(dir(d1))
Out[77]: 2
甚至 None 也有属性...
In [78]: dir(None)
Out[78]:
['__class__',
'__delattr__',
'__doc__',
'__format__',
'__getattribute__',
'__hash__',
'__init__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__']
您可以创建一个没有任何“公共”属性和方法的对象:
class Bare(object):
pass
但是这个对象会有一些内部/标准的方法和属性:
>>> x = Bare()
>>> dir(x)
['__class__',
'__delattr__',
'__doc__',
'__format__',
'__getattribute__',
'__hash__',
'__init__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__']
Python 没有强制私有方法和属性的概念,一切都是公开的。但是,按照惯例,您应该避免外部访问以 开头的方法和属性_
,这些应该保留供内部使用(Python 内部方法使用双下划线)。在实践中,您可以检查没有任何“公共”属性的实例:
>>> filter(lambda a: a[0] != '_', dir(x))
[]
>>> len(filter(lambda a: a[0] != '_', dir(x)))
0
即使您通过覆盖__dir__
and来作弊__getattribute__
,内置属性仍然存在,并且可以__getattribute__
从父类中使用(感谢martineau指出我这一点):
class FakeEmpty:
def __dir__(self):
return []
def __getattribute__(self, name):
raise AttributeError("'{0}' object has no attribute '{1}'".format(type(self).__name__, name))
>>> e = FakeEmpty()
>>> object.__getattribute__(e, '__class__')
__main__.Empty
所以答案是:不是真的,但你几乎可以伪造它。