实例变量:即对象属性是在__init__中定义的。访问或调用实例变量的正确方式是"对象名.变量名"或者"self.变量名"
class Dog:
def __init__(self, name):
self.name = name # 实例变量
def run(self): # 实例方法
print(self.name + "在跑步")
def eat(self):
print("{}在吃饭".format(self.name)) # 实例方法
self.run() # 普通方法中调用普通方法
dog = Dog("金毛")
dog.eat()
# 打印输出
# 金毛在吃饭
# 金毛在跑步
类变量:类变量定义在类中且在函数体之外。访问或调用类变量的正确方式是"类名.变量名"或者"self.__class__.变量名"或者cls.变量名"
类方法:方法上面用@classmethod进行修饰,且参数不在是self,而是cls
class Dog:
name = "金毛" # 类变量
@classmethod
def test(cls):
print(cls.name) # 类方法中调用类变量
Dog.test()
Dog.name # 调用类变量
# 打印输出
# 金毛
class Dog:
__name = "狗" # 类变量
@classmethod
def update_name(cls, name): # 类方法中修改类变量
cls.__name = name
@classmethod
def show_name(cls): # 类方法中调用类变量
print(cls.__name)
Dog.update_name("大熊猫")
Dog.show_name()
# 打印输出
# 大熊猫
类方法是有参数的,静态方法没有参数
类方法,静态方法加载优先于对象
静态方法:方法上面用@staticmethod进行修饰。调用"类名.变量名"
class Person:
name = "小明"
@staticmethod
def test(): # 静态方法
print(Person.name)
Person.test()
在对象初始化的时候调用,我们一般将它理解为"构造函数"
class Phone:
def __init__(self, name): # 初始化方法
self.brand = name
def call(self): # self是对象自己,造函数时系统默认添加
print("正在访问self:", self)
print("我正在用" + self.brand + "给你打电话")
phone = Phone("苹果")
phone.call()
# 打印输出
# 正在访问self: <__main__.Phone object at 0x000001CF339AF5C0>
# 我正在用苹果给你打电话
当我们调用apple = Apple() 的时候调用,
__init__
并不是第一个执行的,__new__
才是。所以准确来说,是__new__
和__init__
共同构成了"构造函数".
__new__
是用来创建类并返回这个类的实例, 而__init__
只是将传入的参数来初始化该实例.
class Apple:
def __new__(cls, *args, **kwargs):
print("step:1")
return super().__new__(cls)
def __init__(self):
print("step:2")
apple = Apple()
# 打印输出
# step:1
# step:2
和java的toString()方法类似
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return '姓名是:' + self.name + ',年龄:' + str(self.age)
p = Person('tom', 18)
print(p)
# 打印输出
# 姓名是:tom,年龄:18
将对象当成函数进行调用时必须重写call
class Person:
def __call__(self, name):
print('执行对象得到参数是:', name)
p = Person()
p('jack')
# 打印输出
# 执行对象得到参数是: jack
私有属性和私有方法:以双下划线"__"开头。私有属性或方法不能在类的外部被使用或直接访问,可以在类的内部使用私有变量和私有方法
class Student:
# 定义学生属性
# name和score属于实例变量, 其中__score属于私有变量
def __init__(self, name, score):
self.name = name
self.__score = score
# 私有方法
def __test(self):
print("hello python")
# 定义打印学生信息的方法
def show(self):
print("Name: {}Score: {}".format(self.name, self.__score)) # 在类的内部访问私有变量
# 可以在类内部调用私有方法
self.__test()
s = Student("小明",100)
s.show()
class People():
def __init__(self):
# 定义私有属性
self.__money = 99
# 获取私有属性值
@property
def money(self):
# 返回私有属性值
return self.__money
# 设置私有属性值
@money.setter
def money(self, value):
# 设置__number的值
self.__money = value
p = People()
p.money = 499
print(p.money)
# 打印输出
# 499
# python动态添加的属性addr
class Person(object):
def __init__(self, newName, newAge):
self.name = newName
self.age = newAge
laowang = Person("laowang", 20)
print(laowang.name)
print(laowang.age)
laowang.addr = "北京"
print(laowang.addr)
# python动态添加方法:
import types
class Person(object):
def __init__(self,newName,newAge):
self.name = newName
self.age = newAge
def eat(self):
print("...%s正在吃。。"%self.name)
def run(self):
print("...%s正在跑。。"%self.name)
Wang = Person("laowang",20)
Wang.eat()
Wang.run = types.MethodType(run,Wang) # 将run这个函数添加为方法
Wang.run()
# python动态添加静态方法和类方法,注意点,静态方法和类方法都是与类关联的
class Person(object):
def __init__(self,newName,newAge):
self.name = newName
self.age = newAge
def eat(self):
print("...%s正在吃。。"%self.name)
@staticmethod#静态方法
def test():
print("...static method...")
@classmethod#类方法
def test1(cls):
print("...class method...")
laowang= Person("laowang",20)
Person.test = test#添加静态方法,静态方法跟着类走的
Person.test()
Person.test1 = test1#添加类方法,类方法跟着类走的
Person.test1()
# 打印输出
# laowang
# 20
# 北京
# ...laowang正在吃。。
# ...laowang正在跑。。
# ...static method...
# ...class method...
子类共有的东西,被抽取到父类中
子类可以重写父类的某些方法
子类不可以继承父类私有的东西
class Person:
def __init__(self, name, salary):
self.name = name
self.salary = salary
# 获得薪水
def getSalary(self):
return self.salary
class Worker(Person): # Worker 继承 Person
def __init__(self, name, salary, hours, per_hour):
super().__init__(name, salary) # 调用父类的方法
self.hours = hours
self.per_hour = per_hour_money
# 普通员工获得薪水
def getSalary(self): # 子类可以重写父类的方法
# 工作时间 * 每小时的薪水
money = self.hours * self.per_hour_money
self.salary += money
return self.salary
class Manager(Person): # Manager 继承 Person
def __init__(self, name, salary, salemoney, percent):
super().__init__(name, salary)
self.salemoney = salemoney
self.percent = percent
# 经理获得薪水
def getSalary(self): # 子类可以重写父类的方法
money = self.salemoney * self.percent
# 薪水 * 提成百分比
self.salary += money
return self.salary
worker = Worker('老王', 2000, 160, 50)
print("总工资", worker.getSalary())
print('----------------------------------------')
manager = Manager('lucy', 5000, 50000000, 0.001)
print("总工资 ", manager.getSalary())
# 多继承的搜索顺序:D->C1->C2->P1->P1->Object
class P1:
def eat(self):
print('p1--->eat')
def sleep(self):
print('p1--->sleep')
class P2:
def eat(self):
print('p2--->eat')
class C1(P1, P2):
pass
class C2(P1, P2):
def sleep(self):
print('C2---->sleep')
class D(C1, C2):
pass
d = D()
print(D.__mro__) # 搜索父类的顺序
d.eat()
d.sleep()
"""
输出结果
(<class '__main__.D'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <class 'object'>)
p1--->eat
C2---->sleep
"""
python中的多态没有严格的定义
class Person:
def __init__(self, name):
self.name = name
"""
pet既可以接收cat,也可以接收dog,还可以接收tiger,前两者继承宠物类型,都可以接收,
但是老虎没有继承宠物类型,所以要它不能接受。但是python却可以接收,所以要用方法
isinstance进行判断接收
"""
def feed_pet(self, pet): # pet既可以接收cat,也可以接收dog,还可以接收tiger
# isinstance(obj,类) 判断obj是不是该类子类的对象
if isinstance(pet, Pet):
print('{}喜欢养宠物:{},昵称是:{}'.format(self.name, pet.role, pet.nickname))
else:
print('不是宠物类型的')
class Pet:
role = 'Pet'
def __init__(self, nickname, age):
self.nickname = nickname
self.age = age
def show(self):
print('昵称:{},年龄:{}'.format(self.nickname, self.age))
class Cat(Pet):
role = '猫' # 类属性
def catch_mouse(self):
print('抓老鼠....')
class Dog(Pet):
role = '狗' # 类属性
def watch_house(self):
print('看家高手....')
class Tiger:
def eat(self):
print('太可怕了,可以吃人,所以不能养...')
# 创建对象
cat = Cat('花花', 2)
dog = Dog('大黄', 4)
tiger = Tiger()
person = Person('张三')
person.feed_pet(cat)
person.feed_pet(dog)
person.feed_pet(tiger)
# 打印输出
# 张三喜欢养宠物:猫,昵称是:花花
# 张三喜欢养宠物:狗,昵称是:大黄
# 不是宠物类型的
try:
可能出现异常的代码
except:
如果有异常执行的代码
finally:
无论是否存在异常都会被执行的代码
def func():
stream = None
try:
stream = open(r'e:\readme.txt')
container = stream.read()
print(container)
except Exception as err:
print(err)
finally:
print('------finally-----')
if stream:
stream.close()
x = func()
# 多个异常
try:
有可能会产生多种异常
except 异常类型1:
pass
except 异常类型2:
pass
except Exception as err:
pass
# 如果是多个except,异常类型的顺序需要注意,最大的Exception要放到最后
def func():
try:
n1 = int(input('输入第一个数字:'))
n2 = int(input('输入第二个数字:'))
oper = input('输入运算符号(+ - * /):')
result = 0
if oper == '+':
result = n1 + n2
elif oper == '-':
result = n1 - n2
elif oper == '*':
result = n1 * n2
elif oper == '/':
result = n1 / n2
else:
print('符号输入有误!')
except ZeroDivisionError:
print('除数不能为零!!!!')
except ValueError:
print('必须输入数字!!!!')
func()
自定义异常
def register():
username = input('输入用户名:')
if len(username) < 1:
raise Exception('注册失败!用户长度必须1位以上')
else:
print('注册成功!输入的用户名是:', username)
try:
register()
except Exception as err:
print(err)
class singleton:
__instance = None
def __new__(cls):
if cls.__instance is None:
cls.__instance = object.__new__(cls)
return cls.__instance
else:
return cls.__instance
s1 = singleton()
print(s1)
s2 = singleton()
print(s2)