19日目すべてがオブジェクトデコレータです:プロパティセッターdelete classmethodstaticmethodバインドされたメソッドとバインドされていないメソッド継承の基本知識最初に抽象化してから継承します

クラスとオブジェクトに組み込まれているいくつかのデコレータと関数

プロパティ:通常、非表示のプロパティで使用されます

classmethod:クラスにバインドされたメソッド、クラスにバインドされたメソッド、誰が呼び出しても、自動的にクラスに渡されます

staticmethod:クラスやオブジェクトにバインドされていません。呼び出した人は誰でも通常の関数です。

すべてがオブジェクトコードの原則です

class Student:
    n = 0

    def __init__(self, name, age, gender):
        Student.n += 1
        self.name = name
        self.age = age
        self.gender = gender

    def choose(self):  # self = obj1
        print("hello %s" % self.name)


obj1 = Student("nana", 18, "female")
print(type(obj1))
print(Student)
print(obj1.__dict__)
obj1.choose()      #对象调函数传参
Student.choose(obj1)     #类调函数传参

内置类=内置类型
print(list)
l1 = list([1, 2, 3])
print(type(l1))
print(l1)
l1.append(4)  #[1, 2, 3, 4]
list.append(l1, 4)  # [1, 2, 3, 4]

デコレータ:プロパティ
プロパティ:通常、非表示のプロパティと組み合わせて使用​​されます。プロパティによって装飾された関数は、関数属性の関数をデータ属性の関数として直接偽装できます。

class People:
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height

    @property   #被property装饰过的函数可以不用再加()运行,直接将bmi伪装成数据属性的函数
    def bmi(self):
        return self.weight / (self.height ** 2)


p1 = People("dada", 75, 1.8)

print(p1.bmi)

同じ属性が追加されていないため、削除、変更、確認できます

class People:
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter  # 函数名.setter装饰过的函数,可以直接修改形参x.可以直接写成p1.name="lala")
    def name(self, x):
        if type(x) is not str:
            raise Exception("名字必须是字符串类型")  # raise Exception主动抛出异常
        self.__name = x

    @name.deleter
    def name(self):
        print("不允许删除")


p1 = People("nana")
print(p1.name)  # 调用查看名字的接口

p1.name = "lala"  # 调用修改名字的接口
print(p1.name)

del p1.name  # 调用删除接口
print(p1.name)


写法二:
class People:
    def __init__(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    def set_name(self, x):
        if type(x) is not str:
            raise Exception("名字必须是字符串类型")  # raise Exception主动抛出异常
        self.__name = x

    def del_name(self):
        print("不允许删除")

    name = property(get_name, set_name, del_name)


p1 = People("nana")  # 调用查看名字的接口
print(p1.name)

p1.name = "lala"  # 调用修改名字的接口
print(p1.name)

del p1.name  # 调用删除接口

バインドされたメソッドとバインドされていないメソッド
バインドされたメソッド
機能:バインドする人は誰でも呼び出す必要があり、呼び出す人は最初のパラメーターとして渡されます

バインドさ
れていないメソッドの機能:クラスやオブジェクトにバインドされていないため、誰でも呼び出すことができますが、誰が呼び出しても、通常の関数であり、自動パラメーター転送効果はありません。

class People:
    def __init__(self, name):
        self.name = name

    # 但凡在类中定义一个函数,默认就是绑定给对象的,应该由对象来调用,
    # 会将对象当作第一个参数自动传入
    def tell(self):
        print(self.name)


    # 类中定义的函数被classmethod装饰过,就绑定给类,应该由类来调用
    # 类调用会将类本身当作第一个参数自动传入
    @classmethod  # classmethod会将函数f1绑定给类People
    def f1(cls):  # cls=People
        print(cls)

    # 类中定义的函数被staticmethod装饰过,就成了一个非绑定的方法即一个普通函数,谁都可以调用
    # 但无论谁来调用就是一个普通函数,没有自动传参的效果
    @staticmethod  # staticmethod会将函数f2变成非绑定方法的普通函数
    def f2(x, y):
        print(x, y)

p1 = People("nana")
p1.tell()

print(People.f1)  # 打印结果显示为一个绑定方法<bound method People.f1 of <class '__main__.People'>>
People.f1()

People.f2(1, 2)
p1.f2(3, 4)

デコレータのユースケース

import setting



class People:
    def __init__(self, name, age, gender):
        self.id = self.creat_id()
        self.name = name
        self.age = age
        self.gender = gender

    def tell_info(self):
        print(self.name, self.age, self.gender)

    @classmethod  # 绑定给类的方法应该由类去调用,如果对象去调用还是会自动传入类的参数
    def from_conf(cls):  # 导入模块setting,从配置文件读取文件完成实例化
        return cls(setting.name, setting.age, setting.gender)

    @staticmethod  # 非绑定方法
    def creat_id():
        import uuid
        return uuid.uuid1()


p1 = People("lala", 18, "male")

p2 = People.from_conf()
print(p2.__dict__)

print(p1.creat_id())
print(People.creat_id())

print(p1.__dict__)

継承
継承は、新しいクラスを作成する方法です。
新しいクラスはサブクラスと呼ばれます。
継承されたクラスは、親クラス、基本クラス、およびスーパークラスと呼ばれます。継承
の特徴は、サブクラスが親クラスの属性を継承できることです。

クラスはオブジェクト間の冗長性の問題を解決するために使用され、
継承はクラス間の冗長性の問題を解決するために使用されます。
継承には結合特性があり、オブジェクト指向の強力な拡張性とは対照的です。継承には注意が必要です。使用には注意が必要です。

新しいスタイルのクラスとクラシッククラス。
オブジェクトクラスとその子孫を継承するサブクラスはすべて新しいスタイルのクラスです。
逆に、クラシッククラスです。

python2には新しいスタイルのクラスとクラシッククラスがあります。python3では、デフォルトですべて新しいスタイルのクラスです。python2で
クラシッククラスを新しいスタイルのクラスに変更する場合は、クラス名の後に(オブジェクト)を追加する必要があります。 。


在python中支持多继承
class Parent1:
    pass


class Parent2:
    pass


class Sub1(Parent1):
    pass


class Sub2(Parent1, Parent2):
    pass


print(Sub1.__bases__)  # (<class '__main__.Parent1'>,)
print(Sub2.__bases__)  # (<class '__main__.Parent1'>, <class '__main__.Parent2'>)

print(Parent1.__bases__)  # (<class 'object'>,)
print(Parent2.__bases__)  # (<class 'object'>,)

最初に抽象化し、次に継承します

継承は、子クラスと親クラスの関係、つまり何が何であるかの関係を表します。この関係を見つけるには、最初に抽象化してから継承する必要があります。
抽象化とは、類似またはより類似した部分を抽出することです

抽象化には2つのレベルがあります。

1.オバマとメッシのより類似した部分をカテゴリに抽出します。

2.親カテゴリとして、人、豚、犬の3つのカテゴリのより類似した部分を抽出します。

抽象化の主な機能は、カテゴリを分割することです(懸念を分離し、複雑さを軽減するため)

ここに画像の説明を挿入
継承:抽象化の結果に基づいています。プログラミング言語でそれを実現するには、継承によって抽象構造を表現する前に、まず抽象化のプロセスを実行する必要があります。
抽象化は、のプロセスにおける単なるアクションまたはスキルです。分析と設計。、クラスは抽象化によって取得できます
ここに画像の説明を挿入

属性検索
の継承継承のコンテキストで属性検索のためのコンテキスト:どれもがオブジェクトに存在しない場合、クラス中がない場合は、オブジェクトの最初の外観は、その後に見て、その後、クラスに見えます親クラス

class Bar:  # Bar的父类不写默认是object
    y = 666


class Foo(Bar):
    def __init__(self, x):
        self.x = x


obj = Foo(111)
print(obj.__dict__)
print(obj.x)
print(obj.y)
示例一:
class Bar:
    def f1(self):
        print("Bar.f1")

    def f2(self):
        print("Bar.f2")
        self.f1()  # obj.f1()


class Foo(Bar):
    def f1(self):
        print("Foo.f1")


obj = Foo()  # Foo.f1
obj.f2()  # Bar.f2


示例二:
class Bar:
    def __f1(self):  # _Bar__f1
        print("Bar.f1")

    def f2(self):
        print("Bar.f2")
        self.__f1()  # _Bar__f1


class Foo(Bar):
    def __f1(self):  # _Foo__f1
        print("Foo.f1")


obj = Foo()  # Bar.f1
obj.f2()  # Bar.f2

おすすめ

転載: blog.csdn.net/Yosigo_/article/details/112489406