1つ、最初の部分
演習1:オブジェクトはインスタンスを直接追加できます
#第一个类对象的测试
class Student:
def __init__(self,name,age):
self.name = name
self.age = age
def get_score(self):
print("{0}分数是:{1}".format(self.name,self.age))
s1 = Student("Clichong",18)
s1.get_score()
s1.salary = 100000 #直接添加实例salary与score
s1.score = 41
print(s1.salary)
s2 = Student("Xioaqi",41)
print(s2.age)
演習2:オブジェクトの例
#以下两行代码运行得出的结果是相同的
a.say_score()
Student.say_score(a)
print(dir(s2))
print(type(s2))
print(s2.__dict__)
print(isinstance(s2,Student))
演習3:クラス属性
#第一个类对象的测试
class Student:
company = "sxt" #类属性
pname = "aic"
def __init__(self,name,age):
self.name = name
self.age = age
def get_score(self):
print("{0}分数是:{1}".format(self.name,self.age))
print(Student.company)
print(Student.pname)
演習4:クラスメソッド
#第一个类对象的测试
class Student:
company = "sxt" #类属性
pname = "aic"
@classmethod #类方法
def PrintCompany(cls):
print(Student.company)
def __init__(self,name,age):
self.name = name #实例属性
self.age = age
def get_score(self): #实例方法
print("{0}分数是:{1}".format(self.name,self.age))
Student.PrintCompany()
演習5:静的メソッド
#第一个类对象的测试
class Student:
company = "sxt" #类属性
pname = "aic"
@staticmethod
def reback(n): #静态方法,但是无法实现递归
if n == 0:
return 1
else:
return n
@classmethod #类方法
def PrintCompany(cls):
print(Student.company)
def __init__(self,name,age): #构造函数
self.name = name #实例属性
self.age = age
def get_score(self): #实例方法
print("{0}分数是:{1}".format(self.name,self.age))
Student.PrintCompany()
print(Student.reback(5))
演習6:呼び出し可能なオブジェクト
__call__メソッドを定義するオブジェクトは「呼び出し可能オブジェクト」と呼ばれます。つまり、オブジェクトは関数のように呼び出すことができます。
#测试可调用方法_call__()
class SalaryAccount:
'''工资计算类'''
def __call__(self, Salary):
print("算工资啦....")
yearSalary = Salary*12
daySalary = Salary//22.5
hourSarlay = Salary//8
monthSalary = Salary
return dict(yearSalary = yearSalary,monthSalary = monthSalary,daySalary = daySalary,hourSarlay = hourSarlay)
def __init__(self,name,salary):
self.name = name
self.salary = salary
def Print(self):
print("hello world")
print(help(SalaryAccount)) #打印出此文档的介绍
s1 = SalaryAccount("aa",2131)
s1.Print()
s2 = SalaryAccount("21",131)
s2.Print()
print(s2(10000))
s3 = SalaryAccount("Clichong",3000)
print(s3.salary)
print(s2.salary)
print(s1.name)
class SalaryAccount:
def __call__(self): #可调用对象设置
return 100
def __init__(self,salary): #构造函数
self.salary = salary
def Print(self): #实例方法
print(self.salary)
s1 = SalaryAccount(1)
s1.Print()
s2 = SalaryAccount(2)
s2.Print()
print(s2()) #调用可调用对象,打印100
演習7:関数を動的に変更する
#测试可调用方法_call__()
class SalaryAccount:
def __call__(self):
return 100
def __init__(self,salary):
self.salary = salary
def Print(self):
print(self.salary)
def Print01(self):
#要注意,此处要带一个参数,否则会报错,因为SalaryAccount累中的Print函数也是带一个参数的
print("好好学习,天天向上")
s1 = SalaryAccount(1)
s1.Print()
s2 = SalaryAccount(2)
s2.Print()
print(s2())
SalaryAccount.Print = Print01
s2.Print() #要注意,此处不可以加参数,因为本来已经存在一个隐含的参数self
補足:
class Myfunction:
pass
class MyAddfunction:
mynum = None
def __call__(self, num): #使得对象可以像函数一样被调用
self.mynum = num
return self.mynum
def __init__(self,num): #构造函数,需要初始化的时候需要使用这个函数
self.mynum = num
def __add__(self, other): #重载+运算符
if isinstance(other,MyAddfunction):
print("myadd_function...")
return self.mynum*other.mynum
else:
print("不是同类,不能相加")
def __mul__(self, other): #重载*运算符
if isinstance(other,MyAddfunction):
print("mymul_function...")
return self.mynum+other.mynum
else:
print("不是同类,不能相乘")
def mywork(s): #在类之外定义两个方法
print("mywork")
def mygame(s):
print("myganme")
MyAddfunction.work = mywork #动态的增加类方法
MyAddfunction.game = mygame
p = MyAddfunction(20)
p.work() #可以正常进行工作
p.game()
演習8:プライベート属性
- テスト1
class Clichong:
def __init__(self,name,salary):
self.name = name
self.salary = salary
def Print(self):
print(self.name)
print(self.salary)
a = Clichong("Tom",10000)
a.Print()
print(dir(a))
2.テスト2
class Clichong:
def __init__(self,name,salary):
self.__name = name #定义私有属性
self.__salary = salary #定义私有属性
def Print(self):
pass
# print(self.name)
# print(self.salary)
a = Clichong("Tom",10000)
#a.Print()
print(dir(a))
3.テスト3
class Clichong:
def __init__(self,name,salary):
self.__name = name #定义私有属性
self.__salary = salary #定义私有属性
def Print(self):
print(self.name)
print(self.salary)
a = Clichong("Tom",10000)
a.Print()
print(dir(a))
4.テスト4
class Clichong:
def __init__(self,name,salary):
self.__name = name #定义私有属性
self.__salary = salary #定义私有属性
def Print(self):
print(self._Clichong__name) #由于已经转变为私有属性,改为指定格式才可以打印
print(self._Clichong__salary)
a = Clichong("Tom",10000)
a.Print()
print(dir(a))
演習9:プライベートメソッド、プライベートクラス変数、プライベート属性
class Clichong:
__myvar = "今年是2020年" #定义私有类变量
def __init__(self,name,salary):
self.__name = name #定义私有属性
self.__salary = salary #定义私有属性
def Print(self):
print(self._Clichong__name) #由于已经转变为私有属性,改为指定格式才可以打印
print(self._Clichong__salary)
def __myprivate(self): #定义私有方法
print("hello Clichong")
def PrintMyvar(self):
print("__myvar:",Clichong.__myvar) #内部调用私有类变量,不需要写成_Clichong__myvar的形式,只需要Clichong.__myvar便可
a = Clichong("Tom",10000)
#私有属性的测试
a._Clichong__salary = 200000 #可以直接修改室友属性
print("a._Clichong__salary:",a._Clichong__salary) #还可以打印出来
#私有类变量的测试
print("a._Clichong__myvar:",a._Clichong__myvar)
a.PrintMyvar()
a._Clichong__myvar = "今年是2021年" #外部直接调用私有的类变量,需要写成_Clichong__myvar的形式,与私有属性一样,与私有方法也一样
print("a._Clichong__myvar:",a._Clichong__myvar)
a.PrintMyvar()
#打印私有属性测试
a.Print()
print(dir(a))
#使用私有方法测试
# a.__myprivate() #会失败
a._Clichong__myprivate() #成功打印
総括する:
- プライベート属性を外部から呼び出す場合、プライベートクラス変数とプライベートメソッドの操作は同じです。どちらも_Clichong__myvar = ""の形式で追加され、p._Clichong__myvarを直接呼び出すことができます。
- 内部でプライベートクラス変数を呼び出すには、Clichong .__ myvar = ""のみが必要です。
演習10:プロパティデコレータの使用
#property装饰器的使用
# @property 修饰的属性,如果没有加 setter 方法,则为只读属性。此处修改报错
#@property 主要用于帮助我们处理属性的读操作、写操作。
class Employee:
def __init__(self,name,salary):
self.name = name
self.__salary = salary
@property
def salary(self):
print("salary:",self.__salary)
return self.__salary
@salary.setter
def salary(self,salary):
if(0 < salary < 100000):
self.__salary = salary
else:
print("录入错误")
a = Employee("Clichong",1000)
print(a.salary)
a.salary = -1433
print(a.salary)
演習11:オブジェクトクラスの__str __()関数を書き直します
class Person:
"Class name is Person"
def __init__(self,name):
self.name = name
def __str__(self):
return "Today is 2020/11/15"
a = Person("Clichong")
print(a)
課題1:クラスメソッドの小規模なテスト
長方形を表すMyRectangleという名前の長方形クラスを設計します。このクラスには次のものが含まれます。
(1)左上隅の頂点の座標:x、y
(2)幅と高さ:幅、高さ
(3)構築方法:x、y、幅、高さを渡します。(x、y)が渡されない場合、デフォルトは0、幅
と高さが渡されない場合、デフォルトは100です。
(4)面積を計算するためのgetArea()メソッドを定義します。
(5)getPerimeter()を定義します。周囲長を計算するメソッド
(6)タートル描画を使用してこの長方形を描画するためのdraw()メソッドを定義します
import turtle
pen = turtle.Pen()
pen.width(5)
pen.color("blue")
pen.showturtle()
class MyRectangle:
def __init__(self,x = 0,y = 0,width = 100,height = 100):
self.x = x
self.y = y
self.width = width
self.height = height
def getData(self):
print("x:",self.x)
print("y:",self.y)
print("width:",self.width)
print("height:",self.height)
def getArea(self):
area = self.height*self.width
print("are:",area)
def getPerimeter(self):
perimeter = 2*(self.width+self.height)
print("perimeter:",perimeter)
def draw(self):
pen.penup()
pen.goto(self.x,self.y)
pen.pendown()
pen.goto(self.x+self.width,self.y)
pen.goto(self.x+self.width,self.y-self.height)
pen.goto(self.x,self.y-self.height)
pen.goto(self.x,self.y)
pen.penup()
#a = MyRectangle(width = 100,height = 200,x = 20,y = 10)
a = MyRectangle(width = 100,height = 200) #直接命名参数
a.getData()
a.getArea()
a.getPerimeter()
a.draw()
while True:
pass
試験結果:
第二に、第二部
演習1:多重継承とポリモーフィズムの実現、スーパー関数の使用
#测试多态的实现
class Animal:
def shout(self):
print("动物叫")
class Dog(Animal):
def shout(self):
print("动物叫,狗也叫")
class Cat(Animal):
def shout(self):
print("动物叫,猫也叫")
class Man(Animal):
def shout(self):
super().shout() #调用父类的shout方法
print("动物叫,人也叫")
class Kid(Dog,Cat,Man): #python语言中额可以一次性继承多个父类
def shout(self):
print("动物叫,小孩叫")
class Child:
def shout(self):
print("小屁孩叫,全都叫")
def DefWhoScout(myobject): #多态的实现
if isinstance(myobject,Animal):
myobject.shout()
else:
print("原来是个小孩叫")
print(Man.mro()) #由于super函数,会打印父类的方法;还会打印自己的方法
print(Dog.mro())
print(Kid.mro()) #验证python中的多重继承
DefWhoScout(Man()) #注意,此处的类对象Man是有括号的Man()
DefWhoScout(Dog()) #注意,此处的类对象Dog是有括号的Dog()
DefWhoScout(Kid())
DefWhoScout(Child()) #因为其没有继承Animal类,故其会执行else语句,而不是自己的shout函数
演習2:オーバーロードされた演算子に関する簡単な説明
#重载运算符的实现
#原本的+运算符的用法
num1 = 10
num2 = 20
result = num1 + num2
print("[+]no change result:",result)
class Myfunction:
pass
class MyAddfunction:
def __init__(self,num):
self.num = num
def __add__(self, other): #重载+运算符
if isinstance(other,MyAddfunction):
return self.num*other.num #[+]的运算规则是相乘
else:
print("不是同类,不能相加")
def __mul__(self, other): #重载*运算符
if isinstance(other, MyAddfunction):
return self.num + other.num # [*]的运算规则是相加
else:
print("不是同类,不能相加")
t0 = Myfunction()
t1 = MyAddfunction(10)
t2 = MyAddfunction(20)
print("t1:",t1.num," t2:",t2.num)
#测试重载后的+运算符
t = t1+t2
print("{0}+{1}={2}".format("t1","t2",t))
#测试重载后的*运算符
t = t1*t2
print("{0}*{1}={2}".format("t1","t2",t))
補足:クラスをオブジェクトにしてから、オーバーロードされた演算子を使用して呼び出すという考え方ですが、結果は失敗します。
#重载运算符的实现
class Myfunction:
pass
class MyAddfunction:
mynum = None
def __call__(self, num): #使得对象可以像函数一样被调用
self.mynum = num
return self.mynum
def __init__(self,num): #构造函数,需要初始化的时候需要使用这个函数
self.mynum = num
def __add__(self, other): #重载+运算符
if isinstance(other,MyAddfunction):
print("myadd_function...")
return self.mynum*other.mynum
else:
print("不是同类,不能相加")
def __mul__(self, other): #重载*运算符
if isinstance(other,MyAddfunction):
print("mymul_function...")
return self.mynum+other.mynum
else:
print("不是同类,不能相乘")
'''''''''
t1 = MyAddfunction()
t2 = MyAddfunction()
t = t1(10)+t2(20) #由于运算符是返回之后再相加,所以没有使用重载的功能
print(t)
'''''''''
t1 = MyAddfunction(10)
t2 = MyAddfunction(20)
t = t1 + t2 #使用了重载的功能
print(t)
概要:__ call__関数をオーバーロードされた演算子で使用できないことを示します。
演習3:浅いコピーと深いコピーに関するディスカッション
- 変数割り当て操作
は、実際には同じオブジェクトを指す2つの変数のみを形成します。 - 浅いコピー
Pythonのコピーは一般的に浅いコピーです。コピーする場合、オブジェクトに含まれるサブオブジェクトの内容はコピーされません。したがって、ソースオブジェクト
とコピーされたオブジェクトは同じ子オブジェクトを参照します。 - ディープコピー
コピーモジュールのディープコピー機能を使用して、オブジェクトに含まれるサブオブジェクトを再帰的にコピーします。ソースオブジェクトとコピーされたオブジェクトの
すべての子オブジェクトも異なります。
概要:
コピー操作ではコンテンツはコピーされません。地質学的割り当てのみが同じコンテンツを指しています。浅いコピーはオブジェクトのコピーですが、オブジェクトの子オブジェクトのコンテンツはコピーされませんが、同じコンテンツを指します。ディープコピーは、オブジェクトをコピーするだけでなく、オブジェクトのサブオブジェクトもコピーします。
import copy
class MobilePhone:
def __init__(self,cpu,screen):
self.cpu = cpu
self.screen = screen
class CPU:
def calculate(self):
print("CPU对象",self)
class Screen:
def show(self):
print("屏幕对象",self)
c = CPU()
s = Screen()
m = MobilePhone(c,s)
m.cpu.calculate()
m.screen.show()
#赋值操作
p1 = m
print("p1:",p1," m:",m) #对象地址没有改变
p1.cpu.calculate() #对象的子对象地址也没有改变,说明还是同一个地址
p1.screen.show()
#浅拷贝操作
p2 = copy.copy(m)
print("p2:",p2," m:",m) #对象地址发生变化,说明拷贝了一个对象
p2.cpu.calculate() #对象的子对象没有改变,说明还是指向统一而个地址
p2.screen.show()
#深拷贝操作
p3 = copy.deepcopy(m)
print("p3:",p3," m:",m) #对象地址改变
p3.cpu.calculate() #子对象的地址也改变,说明是完全拷贝了一个新的
p3.screen.show()
演習4:ファクトリパターンの簡単な例
ファクトリモデルは、作成者と呼び出し元の分離を実現します。特別なファクトリクラスを使用すると、実装クラスが選択され、
統合された管理と制御のためのオブジェクトが作成されます。
# 工程设计模式
class CarFactroy:
def createCar(self,brand):
if brand == "Benz":
return Benz()
elif brand == "BWM":
return BMW()
elif brand == "BYD":
return BYD()
else:
return "Error! Unknowd Brand!"
class Benz:
pass
class BMW:
pass
class BYD:
pass
factory = CarFactroy()
c1 = factory.createCar("Benz")
c2 = factory.createCar("BYD")
print(c1)
print(c2)
演習5:シングルトンパターンの簡単な例
シングルトンパターンのコア機能は、クラスにインスタンスが1つしかないことを確認し、そのインスタンスへのグローバルアクセスポイントを提供することです。
シングルトンモードでは、インスタンスオブジェクトが1つだけ生成されるため、システムリソースのオーバーヘッドが削減されます。構成ファイルの読み取りや他の依存オブジェクトの生成など、オブジェクトの生成にさらに多くのリソースが必要な場合は、「シングルトンオブジェクト」を生成してメモリに永続的に配置できるため、オーバーヘッドが大幅に削減されます。
シングルトンモードを実装する方法はたくさんあります。ここで__new __()を書き換える方法をお勧めします。new()メソッド:オブジェクトの作成に使用されますが、通常、このメソッドを再定義する必要はありません。
#单例模式的其中一种实现方法
class MySingleton:
__obj = None
__init_flag = True #设置一个标志,指允许构造一次
def __new__(cls, *args, **kwargs):
if cls.__obj == None: #如果是空对象,则构建一个对象
cls.__obj = object.__new__(cls) #创建一个新对象
return cls.__obj
def __init__(self,name): #构造函数,希望只构造一次,所以再定义一个标志
if MySingleton.__init_flag:
print("init...")
self.name = name
MySingleton.__init_flag = False #之后永远不会再定义第二个标志
#可以看出,两个是同一个对象
a = MySingleton("Clichong")
print(a)
b = MySingleton("Kacura")
print(b)
class MySingle:
object_flag = None
def __new__(cls, *args, **kwargs):
if cls.object_flag == None:
cls.object_flag = object.__new__(cls)
return cls.object_flag
def __init__(self,number): #不对构造函数作出限定,则其会不断地进行构造然后覆盖,不符合意思
self.number = number
p3 = MySingle(10)
p4 = MySingle(20)
print(p3.number)
print(p4.number)
ps:
・_xxx:メンバーを保護します。「frommoduleimport *」でインポートすることはできません。これらのメンバーにアクセスできるのはクラスオブジェクトとサブクラスオブジェクトのみです。・
・XXXの:システムで定義された特別会員
・__xxx:クラスのプライベートメンバー、唯一のクラスオブジェクト自体がアクセスできる、とサブクラスオブジェクトはどちらかそれにアクセスすることはできません。(ただし、クラス外には「オブジェクト名。_classname__xxx」という特別な方法でアクセスできます。Pythonには厳密な意味でのプライベートメンバーはありません)
課題2:組み合わせの使用
エンジンクラスMotor、シャーシクラスChassis、シートクラスSeat、および車両シェルクラスShell
を定義し、組み合わせ関係を使用して車クラスを定義します。その他の要件は次のとおりです
。Motorクラスのwork()メソッド、seat
クラスのwork()メソッド、およびchassisクラスのwork()メソッドを呼び出す必要があるcarのrun()メソッドを定義します。シャーシ。
class Motor:
def work(self):
print("In Motor Work...")
class Chassis:
def work(self):
print("In Chassis Work...")
class Seat:
def work(self):
print("In Seat Work...")
class Shell:
def work(self):
print("In Shell Work...")
class Car:
def __init__(self,motor,chassis,seat,shell):
self.motor = motor
self.chassis = chassis
self.seat = seat
self.shell = shell
def run(self):
self.motor.work()
self.shell.work()
self.seat.work()
self.chassis.work()
Mo = Motor()
Sh = Shell()
Se = Seat()
Ch = Chassis()
mycar = Car(Mo,Sh,Se,Ch)
mycar.run()
課題3:ファクトリモードとシングルトンモードを使用して、次の要件を達成します
(1)ComputerFactoryクラスComputerFactoryは、コンピューターの製造に使用されます。ファクトリクラスはシングルトンパターンを使用し
ます。つまり、ファクトリオブジェクトは1つしか存在できません。
(2)さまざまなブランドのコンピューターをファクトリークラスで作成できます:Lenovo、ASUS、Shenzhou
(3)さまざまなブランドのコンピューターの継承実装の使用:
(4)親クラスはComputerクラスであり、計算メソッドを定義します。
(5)さまざまなブランドのコンピュータークラスは、親クラスのcalculateメソッドをオーバーライドする必要があります
class ComputerFactory:
__single_flag = None
def __new__(cls, *args, **kwargs): #设置成单例模式
if cls.__single_flag == None:
cls.__single_flag = object.__new__(cls)
return cls.__single_flag
def ProtectComputer(self,brand): #工程模式,没有写构造函数
if brand == "联想":
return Lenovo()
elif brand == "华硕":
return HuaShuo()
elif brand == "神舟":
return ShenZhou()
else:
print("Error! Unknowed Brand!!!")
class Computer: #父类
Flag = 111200
def calculate(self):
pass
#定义三个子类继承父类
class ShenZhou(Computer):
def calculate(self):
print("Produce Shenzhou computer...:",self.Flag)
class Lenovo(Computer):
def calculate(self):
print("Produce Lenovo computer...:",self.Flag)
class HuaShuo(Computer):
def calculate(self):
print("Produce Huashuo computer...:",self.Flag)
#定义两个对象来测试单例模式
myfacture = ComputerFactory()
myotherfacture = ComputerFactory()
print(myfacture)
print(myotherfacture)
#生产不同的电脑测试工厂模式
c1 = myfacture.ProtectComputer("联想") #更换了对象也是无所谓的,因为是同一个对象
c2 = myotherfacture.ProtectComputer("华硕")
c3 = myfacture.ProtectComputer("神舟")
#调用各自改写父类的方法
c1.calculate()
c2.calculate()
c3.calculate()
演習4:プロパティ設定のためのgetメソッドとsetメソッドの混合使用とオーバーロード
Employeeクラスを定義するための要件は、次のとおりです。
(1)属性は次のとおりです。id、name、salary
(2)演算子のオーバーロード+:2つのオブジェクトを足し合わせた場合の給与、および
(3)構築メソッドの要件:入力名、給与、IDを入力しないでください。idは、1000から始まる自己インクリメントの方法を採用し
、最初の新しいオブジェクトは1001で、2番目の新しいオブジェクトは1002です。
(4)salaryプロパティに従って、@ propertyを使用して、プロパティのgetメソッドとsetメソッドを設定します。setメソッドには
、1000〜50000の範囲の数値を入力する必要があります。
class Employee:
employee_id = 1000
def __init__(self,name,salary): #构造函数
self.name = name
self.__salary = salary
self.id = self.employee_id
Employee.employee_id += 1 #实现id自增
def __add__(self, other): #重载+运算符,对象相加返回的是工资相加
if isinstance(other,Employee):
return self.__salary+other.__salary
else:
print("Error! 不是同一种类型")
@property #将函数salary修饰为一个对象,返回的工资金额,也就是赋值与工资保存
def salary(self):
return self.__salary
@salary.setter #限制工资的录入范围
def salary(self,salary):
if(1000 < salary < 50000):
self.__salary = salary
else:
print("Error! Salery Info Error!!!")
#定义了3个对象
emp1 = Employee("Clichong",35000)
emp2 = Employee("Kacura",15000)
emp3 = Employee("Lawrence",25000)
#id自增测试
print("id = {0} name = {1} salary = {2}".format(emp1.id,emp1.name,emp1.salary))
print("id = {0} name = {1} salary = {2}".format(emp2.id,emp2.name,emp2.salary))
print("id = {0} name = {1} salary = {2}".format(emp3.id,emp3.name,emp3.salary))
#重载了+运算符测试
emp = emp1+emp2
print("emp1+emp2=",emp)
emp = emp2+emp3
print("emp2+emp3=",emp)
#property 设置属性的 get 和 set 方法测试
print(dir(emp1))
print("emp1.salary:",emp1.salary,"emp1._Employee__salary:",emp1._Employee__salary)
emp1.salary = 10500 #property修饰器使得salary函数变成了一个对象去使用
print("emp1.salary:",emp1.salary,"emp1._Employee__salary:",emp1._Employee__salary)
emp1.salary = -1000 #会报错,因为超出了范围
print("emp1.salary:",emp1.salary,"emp1._Employee__salary:",emp1._Employee__salary)
emp1.salary = 45000 #emp1的salary又重新被修改为45000
print("emp1.salary:",emp1.salary,"emp1._Employee__salary:",emp1._Employee__salary)