python高度なプログラミング-入門文法(一)

31845 ワード

メタクラス
pythonではすべてオブジェクト、クラスもオブジェクトですが、クラスはオブジェクトを作成するオブジェクトです.クラスでは動的にクラスを作成できます.たとえば、
def func(name):
    if name == "Plane":
        class Plane(object):
            pass
        return Plane
     else:
        class Metrorolite(object):
            pass
        return Mrtroolite

上記のコードに基づいてクラスを動的に作成できますが、クラス全体のコードは作成する必要があります.
type()には2つの役割があります.
1、検査対象タイプ
class People(object):
    def __init__(self, id, name, employees):
        self.id = id
        self.name = name
    
    def func(self):
        return

if __name__ == "__main__":
    id = 1001
    name = "abc"
    employees = [1,2,3]
    people = People(id, name, employees)
    #     
    print(type(id))   # 
    #       
    print(type(name))   # 
    #      
    print(type(employees))  # 
    #        
    print(type(people))    #  
    #      
    print(type(People))    # 
    #      
    print(type(people.func))   #   

#           type()       type  ,           

2、もう一つの大きな役割は、動的にクラスを作成することです.
構文:type(クラス名、親クラス名からなるメタグループ(空でもよい)、属性を含む辞書(名前と値)
戻り値はクラスです
#   
Chinese = type("People", (), {})

#
Chinses = type("People", (object, ), {})

#       (       )   (       ,       、   、    )

def sayHI(self):
    print("HI")

@classmethod
def sayHello(cls):
    print("Hello")

@staticmethod
def sayBye():
    print("Bye")

Chinese = type("People", (object, ), {"id": 1001, "name": "zhangsan", "func1": sayHI, "func2": sayHello, "func3": sayBye})

# Chinese     ,People   ,Chinese       

メタクラスの定義:
メタクラスとは、クラスを作成するための「もの」です.
メタクラスはクラスのクラスで、クラスのテンプレートです
メタクラスは、クラスがオブジェクトを作成するテンプレートであるように、クラスの作成方法を制御するために使用されます.メタクラスの主な目的は、クラスの作成動作を制御することです.
メタクラスのインスタンス化の結果は、クラスのインスタンスがオブジェクトであるようにclassで定義したクラスです.
typeはpythonの内蔵メタクラスで、生成クラスを直接制御するために使用されます.
pythonでclassで定義されているクラスは、typeクラスがインスタンス化されたオブジェクトです.
もちろん、自分のメタクラスを作成することもできます.typeを継承する必要があります.
メタクラスの定義と使用:
関数を使用してメタクラスを返します.
#      
def summary(a, b):
    return a+b


#
def upper_attr(future_class_name, future_class_parent, future_class_attr):

    #                     
    newAttr = {}
    for name, value in future_class_attr.items():
        if name == "bar":
            newAttr[name] = "      "
        if name == "func":
            newAttr[name] = summary

    return type(future_class_name, future_class_parent, newAttr)


class Operation(object, metaclass=upper_attr):
    bar = "      "
    func = None


if __name__ == "__main__":
    print(Operation.bar)    #       
    print(Operation.func(2, 4))    #    6

typeを継承してメタクラスを生成します(ブロガーも理解していません.理解すればいいです.ごくわずかに使用します):
class Meta(type):
    def __init__(cls, *args, **kwargs):
        super().__init__(*args)

    def __new__(cls, *args, **kwargs):
    name, bases, attrs = args
    return super().__new__(cls, name, bases, attrs)
class M_Class(metaclass=Meta):
  def __new__(cls, *args, **kwargs):
    return super().__new__(cls)
  def __init__(self):
    pass

 
ダイナミック言語
静的言語と動的言語の違い:
静的言語(強い言語)静的言語は、コンパイル時に変数のデータ型を決定できる言語であり、多くの静的言語では、変数を使用する前にデータ型を宣言する必要があります.
例:C+、Java、Delphi、C#など.
動的言語(弱い言語)動的言語は、実行時にデータ型を決定する言語です.変数を使用する前にタイプ宣言は必要ありません.通常、変数のタイプは割り当てられた値のタイプです.
例えば、PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix Shellなど.
動的言語の機能:
実行中にオブジェクトにバインド(追加)するプロパティ
実行中にクラスにバインド(追加)するプロパティ
実行中にクラスにバインド(追加)する方法
実行中の属性、メソッドの削除
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

def show():
    print("          .")
@classmethod
def show2(cls):
    print("          ,    id.", cls.id)
    
if __name__ == "__main__":
    person = Person("  ", 22)

    #
    person.phone = "1847015XXXX"
    print(person.phone)       # 1847015XXXX

    #      ,         ,     
    # person.func = show
    # person.func()

    #
    Person.id = 10001
    print("       ", person.id)  #        10001
    print("      ", Person.id)    #        10001
    #            
    Person.func = show
    Person.func()               #            .
    #             
    Person.func = show2
    Person.func()           #             ,    id。10001

__slots__
  __slots__機能:
Pythonではclassを定義するときに特殊な変数__を定義できます.slots__を使用してclassが追加できる属性を制限します.現在のクラスでは定義または追加できません.slots__以外の属性
  __slots__注意事項:
    __slots__クラスのインスタンス化オブジェクトのみを制限し、クラスを制限しません.slots__変数値はメタグループで表されます
    __slots__クラスオブジェクトのプロパティだけでなく、クラスオブジェクトのメソッドも制限します.
    __slots__現在のクラスのみが機能し、継承されたサブクラスは機能しません.
サブクラスで定義__slots__,サブクラスが定義できる属性は、自身の__です.slots__親を付ける_slots__
class Person(object):
    __slots__ = ("name", "age")
    def __init__(self, name, age):
        self.name = name
        self.age = age
    
if __name__ == "__main__":
    person = Person("  ", 22)
    #      ,                name,age 
    # person.phone = "1847015XXXX"
    # print(person.phone)
    
    #      ,      ,__slots__     
    Person.id = 10001
    print("       ", person.id)  #         10001
    print("      ", Person.id)   #        10001

 
ビルダー
コンセプト:Pythonでは,このように循環しながら計算するメカニズムをジェネレータ:generatorと呼ぶ.
ジェネレータを作成するには、次の2つの方法があります.
方法1:リスト生成式の[]を()に変更する
      numbers = ( i for i in range(100))
next()関数によるジェネレータの次の戻り値の取得
より多くの要素がない場合、StopIterationの異常を放出します.
正しい方法は、ジェネレータも反復可能なオブジェクトであり、StopIteration異に関心を持つ必要がないため、forループを使用することです.
メソッド2:関数を使用してジェネレータ(インスタンス)を作成する
#       
def fibonacci(num):
    a = 0
    b = 1
    count = 0
    temp = 1
    while count < num:
        yield b
        a, b = b, a+b
        count += 1

fi = fibonacci(4)
print(next(fi))    # 1
print(next(fi))    # 1
print(next(fi))    # 2
print(next(fi))    # 3

#         ,   StopIteration    
#          for   ,            ,       StopIteration   
print(next(fi))    # error

#
fi = fibonacci(10)
while True:
    try:
        print(next(fi))
    except StopIteration as e:
        print(e)
        break

また、ジェネレータはsend(パラメータ値)を介してパラメータを渡すこともできます.
#       
def fibonacci(num):
    a = 0
    b = 1
    count = 0
    temp = 1
    while count < num:
        temp = yield temp*b
        print("temp{}:{}".format(count, temp))
        a, b = b, a+b
        count += 1
fi = fibonacci(10)

print(next(fi))
while True:
    try:
        print(fi.send(1))
    except:
        break

反復器
反復可能オブジェクト:
ここで、まず反復器オブジェクトについて説明します.オブジェクトがforループで遍歴できるオブジェクトは、一般的に反復器オブジェクトです.pythonは、オブジェクトが反復器オブジェクトであるかどうかを識別するIterableクラスを提供します.この方法は、オブジェクトがクラスのオブジェクトに属しているかどうかを識別するためにisinstance()メソッドを使用する必要があります.ここではtype()メソッドは使用できません.type()の役割は、オブジェクトがクラスのインスタンス化オブジェクトであるかどうかを識別することです(falseを継承することによって)
まず、両者の検査対象タイプの違いを簡単に紹介します.
class A:
    def __init__(self):
        pass

class B(A):
    def __init__(self):
        super().__init__()

if __name__ == "__main__":
    a = 123
    #       ,    ,   、  、  、  、         
    print(type(a) == int)     # True
    print(isinstance(a, int))    # True
    
    #
    b = B()
    print(type(b) == B)    # True
    print(isinstance(b, B))    # True
    #              
    print(type(b) == A)    # False
    print(isinstance(b, A))   # True

だから検査対象の場合はisinstance()を採用したほうがいい、
from collections import Iterable

class A:
    def __init__(self):
        pass

class B(A):
    def __init__(self):
        super().__init__()
    
    #        
    def func(self, a):
        yield a
        a = a + 1
        if a == 5:
            return

if __name__ == "__main__":
    b = B()
    print(isinstance(b, Iterable))   #  False
    #               ,   、  、  、  、  
    b = ""
    print(isinstance(b, Iterable))   # True
    #
    a = B()
    b = a.func(0)
    print(isinstance(b, Iterable))   # True

反復器:
next()関数によって呼び出され、次の値を繰り返し返すオブジェクトを反復器:Iteratorと呼びます.
isinstance()を使用して、オブジェクトがIteratorオブジェクトであるかどうかを判断できます.
反復器には2つのケースがあります.
1、ジェネレータ関数で生成されるジェネレータが反復器
2、iter()関数を通じて反復可能なオブジェクトを反復器に変換する
from collections import Iterator

class A:
    def __init__(self):
        pass

class B(A):
    def __init__(self):
        super().__init__()
    
    #        
    def func(self, a):
        yield a
        a = a + 1
        if a == 5:
            return

if __name__ == "__main__":
    b = B()
    print(isinstance(b, Iterator))   #  False
    #               ,   、  、  、  、  
    b = ""
    print(isinstance(b, Iterator))   # True
    #
    a = B()
    b = a.func(0)
    print(isinstance(b, Iterator))   # True
    
    #   iter()      、  、  、  、        
    b = {}
    b = iter(b)
    print(isinstance(b, Iterator))

反復器は、反復器プロトコルを書き換える2つの方法でカスタマイズできます.
反復オブジェクトは反復プロトコルに準拠しており、2つの方法があります.iter__()と_next__()      
      __iter__ 反復オブジェクトを返し、ループの開始時に暗黙的に呼び出します. 
       __next__メソッドは次の値を返し、各サイクルインクリメンタルで暗黙的に呼び出します.    
       __next__より多くの値が返されない場合にStopIteration例外が発生し、ループ構造はこの例外を暗黙的にキャプチャして反復を停止します. 
class Counter:
    def __init__(self, low, high):
        self.current = low
        self.high = high
    
    #           
    def __iter__(self):
        return self
    
    #                    
    def __next__(self):
        if self.current > self.high:
            raise StopIteration
        else:
            self.current += 2
            return self.current -2