Pythonオブジェクト向けプログラミング基礎解析(二)

7121 ワード

Pythonは最近とても怒っていますね.鹿鐖薛之謙よりも怒っています.もちろんプログラマーの間です.次にPythonに関する内容を見てみましょう.
前の記事では、Pythonのオブジェクト向けプログラミングの基礎についていくつかの知識を紹介しましたが、関連項目として、Pythonのオブジェクト向けプログラミングの基礎解析(一)を参照してください.次に、別の記事を見てみましょう.
パッヶージ
1.パッケージ化する理由
カプセル化とは、データ属性とメソッドの具体的な実装の詳細を隠し、1つのインタフェースだけを提供することです.パッケージはオブジェクトがどのように構築されているかに関心を持たなくてもよいが,実際にはオブジェクト向けにおいてパッケージが最も試練レベルである.
2.パッケージはデータのパッケージと関数のパッケージを含み、データのパッケージはプライバシーを保護するためであり、関数のパッケージは複雑さを隔離するためである.
3.データのカプセル化は、属性の前に__を追加することです.

class People:
 def __init__(self,name,age,salary):
  self.name=name
  self.age=age
  self.__salary=salary
p=People('zhang',19,100000)
print(p.name)#zhang
print(p.age)#19
print(p.__salary)#AttributeError: 'People' object has no attribute '__salary'

あれ、新聞が間違っています.オブジェクトの名前空間を開けて、何が起こったのか見てみましょう.

print(p.__dict__)#{'name': 'zhang', 'age': 19, '_People__salary': 100000}

ああ、pythonが_salaryが形成されましたPeople__salary、もう一度

print(p._People__salary)#100000

したがって、Pythonでは絶対的な非表示はありません.これを知っていれば、これらの変形操作を非表示にすることはありません.クラスの定義フェーズまたはオブジェクト定義(インスタンス化フェーズ)フェーズでのみ発生します.
外部では直接アクセスできませんでしたがのプロパティですが、クラス内でアクセスできるのは、定義フェーズで__に遭遇する限り、このように理解できます.冒頭のPython解釈器は自動的に_クラス名_プロパティなので、クラス内でアクセスできます.そうすれば、ちょっとしたことができます.
まずこれを見てみましょう

class A:
 def foo(self):
  print('from A foo')
  self.bar()
 def bar(self):
  print('from A bar')
class B(A):
 def bar(self):
  print('from B bar')
b=B()
b.foo()  #from A foo
      #from B bar     ,           ,      

親クラスのbar()関数を呼び出したい場合は?どうすればいい

class A:
 def foo(self):
  print('from A foo')
  self.__bar()
 def __bar(self):
  print('from A bar')
class B(A):
 def __bar(self):
  print('from B bar')
b=B()
b.foo() #from A foo
  #from A bar             

4.パッケージの応用
1)データ属性がどのように定義されているかを外部に見せないで、私たちが提供したインタフェースを通じて、外部に見ることができる内容を見るしかありません.

class People:
 def __init__(self,name,age,height,weight,hobby):
  self.__name=name
  self.__age=age
  self.__height=height
  self.__weight=weight
  self._hobby=hobby
 def tell_info(self):
  print('''
  name:%s
  age:%s
  height:%s
  weeight:%s
  '''%(self.__name,self.__age,
    self.__height,self.__weight))
p=People('zhang',18,1.90,75,'read')
p.tell_info()

2)より一般的なシーンは,データの種類を制限し,自分の論理を追加してからユーザにカプセル化できることである.

 def tell_name(self):
  print(self.__name)
 #    
 def set_name(self,new):
  if not isinstance(new,str):
   raise TypeError('          ')
  self.__name=new

5.上記の操作を見て、ユーザーが名前を表示するときはp.tell_name()は、もともとデータ属性だったのに、私たちに関数にされてしまいました.どうやって偽装すればpropertyという装飾器が使えますか.

class People:
 def __init__(self,name,age,height,weight,hobby):
  self.__name=name
  self.__age=age
  self.__height=height
  self.__weight=weight
  self._hobby=hobby
 @property
 def name(self):
  return self.__name
p=People('zhang',18,1.90,75,'read')
print(p.name)#zhang

データ属性には、変更、削除操作も必要です.

 @property
 def name(self):
  return self.__name
 #name   property   ,  setter deleter
 @name.setter
 def name(self,new):
  if not isinstance(new,str):
   raise TypeError('          ')
  self.__name=new
 @name.deleter
 def name(self):
  del self.__name
p = People('zhang', 18, 1.90, 75, 'read')
print(p.name)#zhang
p.name='can' #  
print(p.name)#can
del p.name #  
print(p.name)#AttributeError: 'People' object has no attribute '_People__name'

1.マルチステート
多態の概念は今になってやっと言ったが、私たちはずっと使っている.多態は多様な形態の意味で、動物は猫、犬、豚など、これらは動物の多様な形態である.
Pythonに反映されると,マルチステートは変数が参照するオブジェクトタイプが何であるか分からなくても操作できることを意味する.例えば、シーケンスタイプには長さを計算する方法len()があります.では、シーケンスタイプxを手に入れます.xがどんなタイプなのかを知る必要はありません.シーケンスタイプであることを知るだけで、len(x)の方法でxの長さを計算することができます.これが多態性で、Python自体が多態です
もちろん,データ型を判断するために内蔵関数isinstance()を学んだことがあるが,これは多態優美な特性に合わない.
2.バインド方法と非バインド方法
クラスで定義されている関数は2つあります.バインド方法と非バインド方法です.
1)バインド方法
バインドメソッドは、クラスにバインドするメソッドと、オブジェクトにバインドするメソッドに分けられます.
クラスに定義され、どんな装飾器にも修飾されていない方法は、オブジェクトにバインドするための方法です.
特徴はobj.func()はobjを最初のパラメータとして自動的に入力します.funcの論理はobjを処理することです.
クラスで定義されたclassmethod装飾器で修飾される方法は、クラスにバインドされる方法です.
特徴はcls.func()はクラスclsを最初のパラメータとして自動的に伝達します.funcの論理はclsを処理するため、オブジェクトがこの関数を呼び出しても、クラスを最初のパラメータとして伝達します.

class People:
 def __init__(self,name):
  self.name=name
 def bar(self):
  print('----->',self.name)
 @classmethod
 def func(cls):
  print(cls)
p1=People('zhang')
p1.func() #
People.func()#

2)非バインド方法
クラスにもオブジェクトにもバインドされない非バインドメソッドもあります
staticmethodで飾る

#   :pickle_test
import hashlib
import time
import pickle
import os
student_path=r'C:\Users\Administrator\PycharmProjects\test\student'
class People:
 def __init__(self,name,sex,user_id):
  self.name=name
  self.sex=sex
  self.user_id=user_id
  self.id = self.create_id()
 def tell_info(self):
  print('''
  --------%s info--------
  id:%s
  name:%s
  sex:%s
  user_id:%s
  ''' %(self.name,self.id,self.name,self.sex,self.user_id))
 def create_id(self):
  m=hashlib.md5()
  m.update(self.name.encode('utf-8'))
  m.update(self.sex.encode('utf-8'))
  m.update(str(self.user_id).encode('utf-8'))
  return m.hexdigest()
 def save(self):
  with open(self.id,'wb') as f:
   pickle.dump(self,f)
 @staticmethod #     ,      ,        ,    ,     
 def get_all():
  res = os.listdir(student_path)
  for item in res:
   file_path=r'%s\%s' %(student_path,item)
   with open(file_path,'rb') as f:
    obj=pickle.load(f)
    obj.tell_info()
#    .py
from pickle_test import People
p=People('zhang','male',123123123)
p.get_all()

3.ソフトウェア開発規範
本当のソフトウェア開発の過程で、すべてのコードを1つのファイルに書いたわけではありません.想像してみてください.1つの小さなプログラムには10000行のコードがあり、1つのファイルに書いてあるとしたら、あなたはまだこの仕事をしていますか.
正しい方法はプログラムを1つのモジュールに分解することです.例えばよく使われるbinディレクトリは実行可能なファイルを放して、confディレクトリは配置ファイルdbディレクトリはデータを放して、logディレクトリはログファイルを放して、libディレクトリはライブラリを放して、srcディレクトリはいくつかの重要なコードを放して、例えば重要な論理、クラスの定義など
まとめ
以上,Pythonのオブジェクト向けプログラミングの基礎解析のすべてについて述べたが,皆さんの役に立つことを願っている.興味のある方は引き続き当駅:Python探索のModelFormコードの詳細、pythonでrequestsがホームページに登って文字化けし問題の解決方法の紹介などを参照してください.不足点があれば、コメントを歓迎します.友达の本駅に対する支持に感谢します!