Pythonでは、すべてのデータはオブジェクトであり、すべてのオブジェクトには属性とメソッドが必要です。誰かが属性やメソッドのないPythonオブジェクトを知っていますか?
>>> len(dir(1))
64
Pythonでは、すべてのデータはオブジェクトであり、すべてのオブジェクトには属性とメソッドが必要です。誰かが属性やメソッドのないPythonオブジェクトを知っていますか?
>>> len(dir(1))
64
これは、 andをオーバーライド__dir__
することで簡単に実現でき__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:
、十分です。)
属性を持たないそのようなオブジェクトに出くわしたことはありません..以下を参照してください
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__']
はい!(またはいいえ...)
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...)
「パブリック」属性とメソッドなしでオブジェクトを作成できます。
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__
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
答えは、そうではありませんが、ほとんど偽物であるということです。