-2

在python中,所有数据都是对象,任何对象都应该有属性和方法。有人知道没有任何属性和方法的python对象吗?

>>> len(dir(1))
64
4

4 回答 4

2

这很容易通过覆盖__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__'

(在中,Empty需要是新式类,所以class Empty(object):是必需的;在中,旧式类已经灭绝,所以class Empty:就足够了。)

于 2012-07-18T08:39:04.393 回答
1

是的!(或者没有...)

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...)
于 2012-07-18T08:39:23.153 回答
1

没有遇到任何这样的对象,它没有任何属性..见下文

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__']
于 2012-07-18T08:21:17.117 回答
0

您可以创建一个没有任何“公共”属性和方法的对象:

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

所以答案是:不是真的,但你几乎可以伪造它。

于 2012-07-18T08:21:04.830 回答