特殊メソッドのコードのPythonオブジェクトクラス説明

この記事では、私は必要性の友人を参照することができ、コードを説明するためにPythonオブジェクトのクラスの特別なメソッドについてのあなたを与えるために、小さなに一緒に入れて。
Pythonのバージョン:3.8

class object:
 """ The most base type """
 
 # del obj.xxx或delattr(obj,'xxx')时被调用,删除对象中的一个属性
 def __delattr__(self, *args, **kwargs): # real signature unknown
 """ Implement delattr(self, name). """
 pass
 
 # 对应dir(obj),返回一个列表,其中包含所有属性和方法名(包含特殊方法)
 def __dir__(self, *args, **kwargs): # real signature unknown
 """ Default dir() implementation. """
 pass
 
 # 判断是否相等 equal ,在obj==other时调用。如果重写了__eq__方法,则会将__hash__方法置为None
 def __eq__(self, *args, **kwargs): # real signature unknown
 """ Return self==value. """
 pass
 
 # format(obj)是调用,实现如何格式化obj对象为字符串
 def __format__(self, *args, **kwargs): # real signature unknown
 """ Default object formatter. """
 pass
 
 # getattr(obj,'xxx')、obj.xxx时都会被调用,当属性存在时,返回值,不存在时报错(除非重写__getattr__方法来处理)。
 # 另外,hasattr(obj,'xxx')时也会被调用(估计内部执行了getattr方法)
 def __getattribute__(self, *args, **kwargs): # real signature unknown
 """ Return getattr(self, name). """
 pass
 
 # 判断是否大于等于 greater than or equal,在obj>=other时调用
 def __ge__(self, *args, **kwargs): # real signature unknown
 """ Return self>=value. """
 pass
 
 # 判断是否大于 greater than,在obj>other时调用
 def __gt__(self, *args, **kwargs): # real signature unknown
 """ Return self>value. """
 pass
 
 # 调用hash(obj)获取对象的hash值时调用
 def __hash__(self, *args, **kwargs): # real signature unknown
 """ Return hash(self). """
 pass
 
 def __init_subclass__(self, *args, **kwargs): # real signature unknown
 """
 This method is called when a class is subclassed.
 
 The default implementation does nothing. It may be
 overridden to extend subclasses.
 """
 pass
 
 # object构造函数,当子类没有构造函数时,会调用object的__init__构造函数
 def __init__(self): # known special case of object.__init__
 """ Initialize self. See help(type(self)) for accurate signature. """
 pass
 
 # 判断是否小于等于 less than or equal,在obj<=other时调用
 def __le__(self, *args, **kwargs): # real signature unknown
 """ Return self<=value. """
 pass
 
 # 判断是否小于 less than,在obj<other时调用
 def __lt__(self, *args, **kwargs): # real signature unknown
 """ Return self<value. """
 pass
 
 # 创建一个cls类的对象,并返回
 @staticmethod # known case of __new__
 def __new__(cls, *more): # known special case of object.__new__
 """ Create and return a new object. See help(type) for accurate signature. """
 pass
 
 # 判断是否不等于 not equal,在obj!=other时调用
 def __ne__(self, *args, **kwargs): # real signature unknown
 """ Return self!=value. """
 pass
 
 def __reduce_ex__(self, *args, **kwargs): # real signature unknown
 """ Helper for pickle. """
 pass
 
 def __reduce__(self, *args, **kwargs): # real signature unknown
 """ Helper for pickle. """
 pass
 
 # 如果不重写__str__,则__repr__负责print(obj)和交互式命令行中输出obj的信息
 # 如果重写了__str__,则__repr__只负责交互式命令行中输出obj的信息
 def __repr__(self, *args, **kwargs): # real signature unknown
 """ Return repr(self). """
 pass
 
 # 使用setattr(obj,'xxx',value)、obj.xxx=value是被调用(注意,构造函数初始化属性也要调用)
 def __setattr__(self, *args, **kwargs): # real signature unknown
 """ Implement setattr(self, name, value). """
 pass
 
 # 获取对象内存大小
 def __sizeof__(self, *args, **kwargs): # real signature unknown
 """ Size of object in memory, in bytes. """
 pass
 
 # 设置print(obj)打印的信息,默认是对象的内存地址等信息
 def __str__(self, *args, **kwargs): # real signature unknown
 """ Return str(self). """
 pass
 
 @classmethod # known case
 def __subclasshook__(cls, subclass): # known special case of object.__subclasshook__
 """
 Abstract classes can override this to customize issubclass().
 
 This is invoked early on by abc.ABCMeta.__subclasscheck__().
 It should return True, False or NotImplemented. If it returns
 NotImplemented, the normal algorithm is used. Otherwise, it
 overrides the normal algorithm (and the outcome is cached).
 """
 pass
 # 某个对象是由什么类创建的,如果是object,则是type类<class 'type'>
 __class__ = None
 # 将对象中所有的属性放入一个字典,例如{'name':'Leo','age':32}
 __dict__ = {}
 # 类的doc信息
 __doc__ = ''
 # 类属于的模块,如果是在当前运行模块,则是__main__,如果是被导入,则是模块名(即py文件名去掉.py)
 __module__ = ''

第二に、特定の方法を説明するために使用しました

1 .__ getattribute__方法

1)どのような時間が呼び出されます

私たちが授業で使用OBJこの特定の方法は、オブジェクトである。属性名やGETATTRは(OBJ、プロパティ名)と呼ばれるオブジェクト属性の値を取るとき。例えば:

class Foo(object):
 def __init__(self):
 self.name = 'Alex'
 
 def __getattribute__(self, item):
 print("__getattribute__ in Foo")
 return object.__getattribute__(self, item)
 
 
if __name__ == '__main__':
 f = Foo()
 print(f.name) # name属性存在 或者 getattr(f,name)
 print(f.age) # age属性不存在

かかわらず、プロパティが存在するかどうかの、__ getattribute__メソッドが呼び出されます。属性が存在する場合、属性が存在しない場合、属性の値はNoneが返されない、返されます。

私たちは、プロパティが存在するかどうかを判断するためにはhasattr(OBJ、プロパティ名)を使用することに注意してください、__ getattribute__メソッドが呼び出されます。

差分2)と__getattr__

私たちは、その後、__getattribute__メソッドとメソッド__getattr__違いは何である、あなたは__getattr__メソッドをオーバーライドすることができ、クラスを実現しますか?

私たちは、それが呼び出されます、関係なく、プロパティが存在するかどうかの__getattribute__方法を知っています。プロパティがコールを存在しない__getattr__場合にのみ、デフォルトでははAttributeErrorがスローされます:「フー」オブジェクトは、このエラーを何属性「年齢」を持っていないが、我々はそれを上書きすることができ、我々は、操作を実行する必要があります。

class Foo(object):
 def __init__(self):
 self.name = 'Alex'
 
 def __getattribute__(self, item):
 print("__getattribute__ in Foo")
 return object.__getattribute__(self, item)
 
 def __getattr__(self, item):
 print("%s不存在,但我可以返回一个值" % item)
 return 54
 
 
if __name__ == '__main__':
 f = Foo()
 print(f.name) # name属性存在
 print(f.age) # age属性不存在,但__getattr__方法返回了54,所以这里打印54。

リターン結果:

__getattribute__ in Foo
Alex
__getattribute__ in Foo
age不存在,但我可以返回一个值
54

私たちは、f.nameを参照してf.ageは__getattribute__メソッドと呼ばれていますが、この方法は、唯一のf.age __getattr__と呼ばれています。そこで、我々は__getattr__は、このような辞書のクラスの値として多くのもの、または処理の異常を行うことができます。

2 .__ setattr__方法
我々はobj.nameを実行「アレックス」またはSETATTR =(OBJ、属性名、属性値)プロパティが割り当てられたときに呼び出されます。

class Foo(object):
 def __init__(self):
  self.name = 'Alex'
 
 # obj.xxx = value时调用
 def __setattr__(self, key, value):
  print('setattr')
  return object.__setattr__(self, key, value)
 
 
if __name__ == '__main__':
 f = Foo()
 f.name = 'Jone' # 打印setattr
 print(f.name)

__setattr__が書き換えられる場合(親クラス__setattr__言葉を呼び出すことはありません)。obj.xxx =値の割り当てを使用するには動作しません。

特に注意が、クラスのコンストラクタである。この方法が割り当て呼び出されたときに初期化されます。

class Foo(object):
 def __init__(self):
  self.name = 'Alex' # 这里也要调用__setattr__
  ...

我々は__setattr__メソッドを書き換える必要があるときは、注意を初期化するために__setattr__オブジェクトクラスの初期化を使用する必要があります。

class Local(object):
 def __init__(self):
  # 这里不能直接使用self.DIC={},因为__setattr__被重写了
  object.__setattr__(self, 'DIC', {})
 
 def __setattr__(self, key, value):
  self.DIC[key] = value
 
 def __getattr__(self, item):
  return self.DIC.get(item, None)
 
 
if __name__ == '__main__':
 obj = Local()
 obj.name = 'Alex' # 向DIC字典中存入值
 print(obj.name) # 从DIC字典中取出值

3 .__ delattr__法
方法デルOBJ。呼び出さプロパティ名とdelattr(OBJ、属性名)の両方に対応します。つまり、プロパティにオブジェクトを削除します。

if hasattr(f,'xxx'): # 判断f对象中是否存在属性xxx
 delattr(f, 'xxx') # 如果存在则删除。当xxx不存在时删除会报错
 # del f.xxx # 同上

4 .__ dir__方法

対応DIR(OBJ)すべてのプロパティとメソッド名のオブジェクトのすべてのプロパティ名を、取得します。

f = Foo()
print(f.__dir__()) # ['name', '__module__', '__init__', '__setattr__', '__getattribute__', '__dir__', '__dict__', '__weakref__', '__doc__', '__repr__', '__hash__', '__str__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__class__']

これは、リストを返します。

5. eq__と__hash
eq__は、オブジェクトがデフォルトの継承行く__eqによって呼び出された判断OBJ ==他と呼ばれています

f1 = Foo()
f2 = f1
print(f1 == f2) # True
print(f1 is f2) # True
print(hash(f1) == hash(f2)) # True

デフォルトでは、F1 == F2、F1は真(または等しくない、偽と同じ)と同時に、F2、ハッシュ(F1)==ハッシュ(F2)する必要があります。

我々は、このような2つのオブジェクトを比較し、比較になっプロパティとして__eq__方法を、書き換えた場合:

class Foo(object):
 def __init__(self):
  self.name = 'Alex' # 这里也要调用__
  self.ccc = object.__class__
 def __eq__(self, other):
  return self.name==other.name

すなわち、self.name == other.name場合、オブジェクトに等しいと見なされています。

f1 = Foo()
f2 = Foo()
print(f1 == f2) # True
print(f1 is f2) # False
print(hash(f1) == hash(f2)) # 抛出异常TypeError错误

私たちはクラスで__eq__メソッドを書き換えた場合、デフォルトは__ = Noneを__hashませんので、なぜハッシュは、例外がスローされます。我々は、ハッシュ(OBJ)を呼び出すときに、__ hash__方法を実行することはできません。

要約:

私たちは、ハッシュクラスのようになりたいではない気づいたとき、あなたは__eq__メソッドをオーバーライドすることができ、その後、書き換え__hash __、__ hash__方法はNoneに設定されていない、このクラスのオブジェクトはハッシュではありません。

__hash__同じハッシュ値インタプリタと、同じ変数の値(型の制限、いくつかのタイプができないハッシュ、例えばリスト)のデフォルト(ハッシュ(OBJ))により提供される方法、様々な通訳のために異なるハッシュ値。私たちは目標をハッシュしたいのであれば、あなたはhashlibモジュールを使用する必要があります。

ハッシュとID間の差は、二つのオブジェクトのハッシュ値が同一の値が同じでなければならないが、IDが異なっていてもよい理論的(同一のメモリアドレスの一意な識別子であるOBJ IDちょうど同じ.ID(OBJ)は、同じオブジェクトでなければなりません。)

6. GTLTGE

これらのサイズは、比較のために、我々は、オブジェクトの大きさを比較する方法の定義から(例えば、前記プロパティの唯一の比較対象値)、それらを書き換えることができるされています。

7. str__と__repr
プリント(OBJ)を印刷するためのコンテンツを定義__str__。

class Foo(object):
 def __init__(self):
  self.name = 'Alex'
 
 def __str__(self):
  return "我是Foo"
 
 
if __name__ == '__main__':
 f1 = Foo()
 print(f1) # 打印 我是Foo

コマンドラインで:

>>> class Foo(object):
...  def __str__(self):
...    return "我是Foo"
...
>>> f1 = Foo()
>>> print(f1)
我是Foo
>>> f1
<__main__.Foo object at 0x0000023BF701C550>

それは__str__言葉を使って見ることができ、印刷は、私たちが指定した値を印刷することができ、およびコマンドライン出力は、オブジェクトのメモリアドレスです。

repr__印刷コンテンツの同時コマンド出力OBJの内容を定義し、印刷のためのpython(OBJ)(__str書き換えていない場合)。

class Foo(object):
 def __init__(self):
  self.name = 'Alex'
 
 def __repr__(self):
  return "我是Foo"
 
 
if __name__ == '__main__':
 f1 = Foo()
 print(f1) # 打印 我是Foo

コマンドラインで:

>>> class Foo(object):
...  def __repr__(self):
...    return "我是Foo"
...
>>> f1 = Foo()
>>> print(f1)
我是Foo
>>> f1
我是Foo

私たちはただ__repr__書き直し、見ることができますが、両方の印刷やダイレクト出力は、私たちが指定した値を印刷します。

我々は__str__と__repr__の両方を上書きする場合:

>>> class Foo():
...  def __str__(self):
...    return "我是Foo---str"
...  def __repr__(self):
...    return "我是Foo---repr"
...
>>> f1 = Foo()
>>> print(f1)
我是Foo---str
>>> f1
我是Foo---repr

情報印刷を担当するstr__ __、2つのメソッドを書き換えるために同時に見られ、コマンドライン出力に直接関与__repr__することができます。

8 .__ new__方法

9 .__ sizeof__方法

10. クラス辞書Module1を、__ doc__内の例題を表示プロパティ

クラスは:生成されているオブジェクトのクラスを返します。

print(f1.__class__) # <class '__main__.Foo'>

辞書:オブジェクトディクショナリのすべての属性を返します

print(f1.__dict__) # {'name': 'Alex'} 只有一个属性name

Module1が:モジュール内のオブジェクトを返します。

class Foo(object):
 def __init__(self):
  self.name = 'Alex'
 
 
if __name__ == '__main__':
 f1 = Foo()
 print(f1.__module__) # 打印__main__

オブジェクト・クラスは、モジュール内の現在実行中の印刷__main__に対応する場合。

import test3
 
f = test3.Foo()
print(f.__module__) # 打印test3

オブジェクトクラスは、他のモジュールに対応する場合、モジュール名が印刷されています。

ドキュメントのコメントが好き:

class Foo(object):
 """
 这是一个类,名叫Foo
 """
 def __init__(self):
  self.name = 'Alex'
 
 
if __name__ == '__main__':
 f1 = Foo()
 print(f1.__doc__) # 打印 这是一个类,名叫Foo

読むためにありがとうございまし
作業コンピューターの基本的な悪い損失を食べて、これが教育を受けていないことが判明し、自己のpythonを、選んだ大学で
唯一補うために取得することができ、できないこと、そして、コーディング外で彼自身のカウンター攻撃をオープンしました道路、常に、組織的、基本的なコンピュータ学習の深い知識をPythonのコア知識を学ぶ、私たちの学習Pythonのバックルqunを置く:250933691、あなたは平凡に不本意であれば、それは外のコーディングの私と一緒で、常にそれを育てます!
実際には、それよりも技術的な、より技術的なものではないだけであり、例えば、プログラマ自身が高貴な存在である、ああ、それはどのようにではなく、「巨根ワイヤー」よりも、細かなプログラマを作ることではないでしょうか?[参加するためにクリック]、あなたは高貴な人になりたいたいに来て!
プログラマーの数は公的機関に集中できるように、csdn2299:@この記事は、公開番号から来ています

公開された16元の記事 ウォンの賞賛0 ビュー6386

おすすめ

転載: blog.csdn.net/haoxuan05/article/details/105301830