オブジェクト指向
PS:何があって、言語、オブジェクト指向の3つの要素がありません:パッケージ(クラス変数や関数をカプセル化して)、継承、多態性
オブジェクト指向(OO、オブジェクト指向の)コードを書くための考え方です:プログラムが構成するものです。オブジェクト指向プログラミング:OOP(オブジェクト指向プログラミング)
クラスは、実際には、抽象化です。それは、同じ特性が分類されているとのことですが、抽象いわゆる。たとえば、Userクラスは、抽象ユーザ情報を一緒に
クラスのプロパティとメソッド。
プロパティ:それはクラスの特性を示しています
メソッド(振る舞い):機能クラスを指定します
シモンズ:こぶ構造の規則、クラス、および大文字の最初の文字
プログラム(クラス)=データ構造(属性)+アルゴリズム(方法、行為)
オブジェクト指向は、処理手順の世界に現実世界をマッピングすることです
特定のクラス:例
自己:現在のオブジェクト(メソッドの呼び出し元)
CLS:オブジェクトのクラス
注:自己またはCLSのいずれか、単に変数名のみ、これら2名の使用に慣れて、あなたはまた、別の名前を使用することができます(現在はしていない学習公式の説明、個人の理解:最初のパラメータのインスタンスメソッド、オブジェクト自体のインスタンスを表し、最初のパラメータ)がそれ自体のクラスのクラスメソッドを表します
デフォルトコンストラクタのパラメータを持っているのpythonはできません
クラスの関数呼び出しで定義された方法でいます
class Cat:
#__new__方法分配内存,单例模式时会用到此方法
def __new__(cls, *args, **kwargs): #new方法为什么需要这些参数?此处这样写只是为了可以接受任何形式与数目的参数,在new里面一般并用不到,但是执行了new之后会自动调用init方法,那时会用到这些参数。亦即:*args与**kwargs并不是必要的格式。比如,在init方法中,如果需要的是除了self之外的一个参数(如name),那么此处也可以只声明一个变量接受该参数即可
print("__new__")
return super().__new__(cls) #也可以:return = object.__new__(cls) 另,此处以本人目前的知识猜测,在object类中应是用了@property修饰了__new__()方法的,所以此处如果用object可以不加括号。加了括号也是一样的
#注意:__new__方法必须要有返回值,返回实例化出来的实例,可以返回父类__new__返回代实例(此处采用的方法),也可以直接将object的__new__出来的实例返回
#构造方法,该方法会创建对象(实例),自动调用
def __init__(self, color, name):
#前后有双下划线的方法由程序自动调用
self.color = color
self.name = name
def catch_mouse(self):
print(self.name + " 正在抓老鼠")
def __del__(self):
print("对象空间已经被释放") #当对象的空间被释放的时候(引用对象的个数为0的时候)会自动调用此方法
#ps:对象的引用个数可以用`import sys \n sys.getrefcount(Object)`来获取,比实际的对象多1,如果该对象空间已经被释放,则会报错
#创建实例
tom = Cat("Blue","Tom")
print(tom.name)
プロセス・オブジェクトの例:
- メモリを割り当て(__new __())、この方法は、単一の際にデザインパターンを使用します。スペースの新しいブロックが、その後、自動的にinitメソッドを呼び出すと、この時点で新しい方法は、自動的に受信したパラメータのinitメソッドに渡されます。新しいスペースは、自己参照のinitメソッドに渡されます
- 初期値(__init __())
__new__()方法的注意事项:__new__方法必须要有返回值,返回实例化出来的实例,可以返回父类__new__返回代实例(此处采用的方法),也可以直接将object的__new__出来的实例返回
プロパティの民営化:
3. XX:下線民営プロパティやメソッドの前に、単一のセットは、オブジェクトにアクセスすることができ、モジュールに直接使用されるが、somemoduleインポート*インポート、クラスとサブクラスから禁止することができます
4.ときに名前付きプロパティ前にプラス「__」、それはそれは文法のルールで、2つのアンダースコアです。
S:XXは、Pythonのキーワードとの競合を回避するために、単一のポストを強調し
、クラスで使用されている私有財産やプライベートメソッドのため、追加しなければならない__
、すなわち、二重下線を
:なぜ民営化(隠された変数)下線倍増させることができ
__dict__:任意のオブジェクトは、このプロパティを持って、インスタンスのすべてのプロパティで満たされています。2つの下線属性で始まり、名前が変換されます:_ __ +クラス名、属性名、今回のことで对象名._类名__属性名
アクセス
プライベートプロパティにアクセスする方法:この方法で
class Student:
"""
学生类
"""
def __init__(self, name, age):
self.__name = name
self.__age = age
def set_name(self, name):
if not len(name) < 3:
self.__name = name
def get_name(self):
return self.__name
#标注,默认是get的。@就是一个标记,比如下面的@age.setter,当用“=”时,就调用该函数。如果是用的".",就调用此方法
@property #@语法糖,前面加这个的可以像使用属性一样使用方法,即不用加括号
def age(self):
return self.__age
#使用了@后方法名必须与属性名一致
@age.setter #让方法可以像属性一样使用
def age(self,age):
self.__age = age
tom = Student("tom", 23)
print(tom.get_name())
tom.set_name("jack")
print(tom.get_name())
tom.hight = 23 #为tom额外添加hiht属性。
print(tom.age) #可直接获得年龄,其实tom.age是在调用方法
tom.age = 18 #使用语法糖的方式更改属性值
print(tom.age) #这里也使用了语法糖,实际上是调用的age方法
#输出:
tom
jack
23
18
プロパティの使用上の第二のアプローチ
class A(object):
def __init__(self):
self.__num = 10
def set_num(self,num):
self.__num = num
def get_num(self):
return self.__num
num = property(get_num,set_num) #这里的方法名可以任意取,则当使用=进行赋值操作时,相当调用第二个方法(设置值的方法),当仅仅是取值的时候,则调用第一个方法(取值的方法),等号前面的变量名必须与属性的变量名一致,但是不用加双下划线
obj = A()
print(obj.num)
obj.num = 15
print(obj.num)
オブジェクト・クラス自体は
、典型的には:クラス属性、クラスのメソッドを動作させるために、オブジェクトを動作させるため、例えば、方法として
自己プロパティ名:インスタンスの属性。
class User:
# 在类里面定义的属性称为类属性,由所有实例共享。一般不在这里面写东西。
num = 0
def __init__(self, name):
self.__name = name
User.num += 1
def print_name(self):
print(self.__name)
print(User.num)
@property
def name(self):
return self.__name
@classmethod # 标注,表明这是类方法。即可以通过类名调用,必须用一个cls参数,cls就是类本身,与对象的self相当。
def creat_user(cls, name, age): # cls其实就是类本身
user = cls(name)
user.age = age
return user
@staticmethod # 静态方法,可以直接通过类名调用。当一个方法即和类没有关系又和对象没有关系时,就用静态方法,就不用cls和self参数
def sum(a, b):
return a + b
def __str__(self): #当print对象的时候会调用这个方法。这个方法必须返回一个字符串
_str = ""
for k,v in self.__dict__.items():
_str += str(k)
_str += ":"
_str += str(v)+" "
return _str
u = User("zhangsan")
u1 = User("lisi")
u.print_name()
u1.print_name()
User.num += 1
print(User.num)
u2 = User.creat_user("wangwu", 20)
# @classmethod修饰的方法是类方法,类方法可以通过类名调用。类方法必须有一个参数,cls,即类本身
print(u2.name)
print(User.sum(1, 3)) #通过类名调用静态方法
print(u.sum(2,4)) #通过实例对象调用静态方法
print(u1.sum(1,3))
u3 = u1.creat_user("laoli",50)
print(u3.name)
print(u1)
受け継ぎます
Pythonサポート多重継承、継承および継承順序関連コンテンツ(最初のクラスから継承されたプロパティ)
サブクラスのオブジェクトは、親クラスのプロパティを持って、親クラスの直接メソッドを呼び出すことができます
すべてのクラスは、デフォルトのオブジェクトクラスを継承します
注:私有財産と親クラスのプライベートメソッドは、(__さんで始まる)継承されていないが、私有財産が継承されている場合の方法(書き換えない)のプライベートプロパティまたは親クラスのメソッド、親クラスを訪問しましたかプライベートメソッドまたはこのメソッドを使用してみましょう
class A:
def __init__(self):
self.name = "A"
def print_test(self):
print("A"*10)
class B(object): #ps:如果一个类没有继承任何类,建议写上object类,object类是所有类最终的父类,即:所有类都继承自object类
def __init__(self):
self.name = "B"
def print_test(self):
print("B"*10)
class C(A): #A是C的父类,又称基类。C是A的子类,派生类。C继承自A
def __init__(self):
super().__init__() #调用父类的初始化方法
self.age = 20
class D(A,B): #多继承,是按照顺序,比如此处有两个name,那么D就继承到了A的。
def print_test(self):
super().print_test()
self.print_test()
c = C()
print(c.name)
print(c.age)
d = D()
print(d.name)
print(C.__mro__) #mro中的顺序是由C3算法决定的
#上面这句会输出:(<class '__main__.C'>, <class '__main__.A'>, <class 'object'>),表明调用C类的对象的方法时,搜索的顺序,如果C没有该方法,就用A的,如果A还没有,就调用object类的(caution,object类是所有类的父类,因为这里A没有继承除了object类之外的类,所以是A中找不到就到object中去找,如果A继承了其他类,比如D类,则A中找不到就会到D中去查找。即查找顺序为:本类>父类(按继承的先后顺序,先继承的先用)>父类的父类
print(isinstance(d,A)) #判断一个对象是否是一个类的实例。输出True,子类的对象也是父类的实例
print(issubclass(D,A)) #判断一个类是否是另一个类的子类
#以上的顺序表明了查找属性的顺序(多继承的访问顺序),如果C本身有,就用C本身的,如果C本身没有,而A有,则用A的,再否则用B的
アヒルタイプ
わずか数クラスが似たような機能や属性を持って、同じ親から継承していない場合であっても、また同じクラスに属していると考えることができます。たとえば、以下のプログラマやマネージャー、同じ親から継承されていないが、スタッフが、それはメソッドやプロパティのために意図的に同様の定義することが可能であることは明らかです
class Programer:
def dowork(self):
print("编程")
class Manager:
def dowork(self):
print("管理")
p = Programer()
m = Manager()
p.dowork()
m.dowork()
#判断某一对象是否是一个类的实例
print(isinstance(p,Programer))
リライト
これはむしろ、親クラスのメソッドよりも、所有することになるメソッド呼び出しを呼び出した後、親クラスとサブクラスのメソッドに同じ名前の定義を書き換える方法です。
class Animal:
name = "狗"
def eat(self):
print("-----吃-----")
def run(self):
print("-----跑-----")
class Dog(Animal):
def bark(self):
print("-----汪汪叫-----")
class XiaoTian(Dog):
def fly(self):
print("-----fly-----")
def bark(self):
print("-----狂叫-----“)
#Dog.bark(self) #通过父类的类名,并以self为参数,可以调用父类中被重写了的方法
super().bark() #通过super().方法名(),可以也可以调用父类被重写的方法,此种方法不需要self参数
xt = XiaoTian()
xt.run()
xt.bark()
xt.eat()
print(xt.name)
ポリモーフィズム
定義:型定義とは、実行時の同じ形ではない場合、この時間はポリモーフィズムと呼ばれています。(シモンズ:C ++およびJavaは多型で広く変化、C ++やJava、多型、鋳造に幾分類似)
class Dog(object):
def print_self(self):
print("This is dog")
class XiaoTianQuan(Dog):
def print_self(self):
print("This is XiaoTianQuan")
def introduce(temp):
temp.print_self()
dog1 = Dog()
dog2 = XiaoTianQuan()
introduce(dog1)
introduce(dog2)
#所谓多态,即写完程序后,只是知道它调用一个方法,但是不确定它究竟是调用基类的还是调用子类的,在真正执行的一刹那,才根据当前的对象是谁去决定调用哪个方法
#因为python是动态类型的语言,所以python中的多态体现得不态明显
Class属性、属性インスタンス
#需求:用一个变量存储一个类创建了多少个对象
class Tool(object):
#属性:定义在类之内,方法之外的属性称为类属性
count = 0
#方法
def __init__(self, name):
self.__name = name
Tool.count += 1 #对于类属性,用类名进行访问(就像实例对象的属性通过实例对象的名字访问一样)
tool1 = Tool("铁锹")
tool2 = Tool("共兵铲")
注意:实际上程序并不是每创建一个对象就在该对象的空间内放一个方法,而是在该空间内多了一个属性(变量),该属性可以知道这个对象的class,即保存了该类的一个引用,然后在调用该方法时到该类中查找该方法。故而一个抽象的类实际上也占用了内存空间,亦即类在程序里面也是一个对象,这个对象称为类对象,通过类创建出来的对象称为实例对象,实例对象里面的属性称为实例属性,类里面的属性称为类属性。
注意:オブジェクトインスタンスの属性と関連するデータ、およびオブジェクトのインスタンスと更なる例は、共有されていない特性です。クラス属性に属するクラスのオブジェクトであり、同じ属性クラスのインスタンスオブジェクトの複数の間で共有することができます。クラス定義のクラスのプロパティは、一度だけオブジェクトのインスタンスを作成するとは何の関係も定義することはできません。
- 例プロパティ
:NO name属性は、クラスの初期化を定義していないと仮定すると、その後続の実施例のインスタンスにより参照されるオブジェクトを作成することができるプロパティ__init__方法およびその後の特性とは、(例えば、属性S.nameようによって=「犬」、 method属性は、インスタンスの属性を作成され、initメソッドで定義された属性が)インスタンス属性を所属します
メソッド、クラスメソッド、静的メソッドの例
注意:实例方法中的第一参数为self只是大家都遵循的一个规则,同时,类方法中的第一个参数cls也只是大家都遵循的规则
class Game(object):
#类属性
num = 0
#实例方法
def __init__(self):
self.name = "laowang"
#在方法前加了@classmethod的都称为类方法
@classmethod #装饰器
def add_num(cls): #不同于实例方法中必须有self参数保存该对象(实例),cls就是用来保存类的引用的,是class的简写。
cls.num = 100
=ゲームゲーム()
#クラスメソッドGame.add_num()クラスの名前で呼び出すことができます。(:また、クラスオブジェクトのインスタンスが作成されたクラスを、ので、このクラスのメソッドを呼び出すことができる個人的な理解)また、クラスメソッドを呼び出すために、このクラスのオブジェクトによって作成することができます
印刷(Game.num)
注意:実際の開発を将来的に、あなたは一般的なカテゴリによって、クラスでそれをしたい場合は、あなたが一般的な関数を使用して機能を実行したい場合。そのクラスは、魚や鳥でもないと機能を持っています
シングルトンデザインパターン
class S:
__instance = None
def __new__(cls, *args, **kwargs):
if S.__instance is None: #类属性通过类名访问
S.__instance = super().__new__(cls) #因为自己重写了__new__方法(分配内存的),所以必须调用父类的__new__()以分配内存
return S.__instance #ps:也可以写成:return cls.__instance
s1 = S()
s2 = S()
print(id(s1),id(s2)) #会发现两个对象的内存地址相同,即他们是同一个对象
#拓展:只初始化一次对象
class S:
__instance = None
__init_flag = False
def __new__(cls, *args, **kwargs):
if S.__instance is None: #类属性通过类名访问
S.__instance = super().__new__(cls) #因为自己重写了__new__方法(分配内存的),所以必须调用父类的__new__()以分配内存
return S.__instance #ps:也可以写成:return cls.__instance
def __init__(self,name):
if Dog.__init_flag == False:
self.name = name
Dog.__init_flag = True