目录
定义类
class Student():
def __init__(self,name,score): ## 构造方法,self是类本身
self.name=name #传入的值赋值给类本身
self.__score=score # 加两个_ 变成private 私有属性,通过类对象不能调用
def print_name(self): # 类方法
print("student name is %s"%self.name) #通过类本本身访问类属性
#封装属性,通过set方法设置属性值,通过get方法获取属性值
def set_score(self,score):
self.__score=score
def get_score(self): #封装属性,通过get获取属性值
if self.score>90:
print('A')
else:
print('B')
# 实例化类 ,生成类对象
s=Student('domain','99') #实例化类 ,生成类对象
s.print_name() #通过类对象调用类方法
# print(s.score) #通过类对象访问类属性
# s.score=100 #通过类对象修改类属性
# print(s.score)
property
对封装好的属性不通过get和set设置 获取,直接通过对象调用
class PropertyDemo(object):
@property #get
def score(self):
return self._score
@score.setter #set
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
p=PropertyDemo
p.score=98
print(p.score)
动态添加类属性,方法,只能为当前对象使用,类的其他对象并不拥有
s.age=18 #给对象添加age属性
print(s.age)
def set_age(self,age): #定义一个方法set_age
self.age=age
from types import MethodType #导入MethodType 模块
s.set_age=MethodType(set_age,s) #给对象s 添加set_age方法,传入要添加的方法和对象
s.set_age(20) #使用刚刚添加的方法
print(s.age)
限制可动态添加的属性
class limit_demo_class:
__slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称,只能动态添加name,age 属性
继承、多态
class Animal(): #父类Animal
age=3
def run(self):
print('I am a animal')
class Dog(Animal): #定义一个子类Dog,继承父类Animal
# def run(self): #子类重写父类run方法
# print('I am a dog')
pass
class Cat(Animal): #定义一个子类Cat,继承父类Animal
def run(self): #子类重写父类run方法
print('I am a cat')
class Pig(Animal): #定义一个子类Pig,继承父类Animal
def run(self): #子类重写父类run方法
print('I am a pig')
dog=Dog()
print(dog.age)#调用父类age属性,因为继承了父类Animal,所以拥有父类属性age,可以直接调用
dog.run() #调用父类run方法,因为继承了父类Animal,所以拥有父类方法run,可以直接调用
cat=Cat()
cat.run() #调用自己run方法,因为在类中重写了run方法,所以此时调用的自己的run方法
多重继承
class Flyable():
def fly(self):
print("I am flying")
class Brid(Animal,Flyable): #继承父类Animal和Flyable
pass
b=Brid()
b.run() #调用Animal的run方法
b.fly() #Flyable的fly方法
新式类
广度优先 和 深度优先
- 广度优先: 横向 执行所有 继承的类
- 深度优先: 纵向 执行所有 继承的类
在多重继承中,同时继承两个父类,调用两个父类中同名的方法,执行哪一个?
- python 2.x 的经典类按深度优先继承, 新式类按广度优先继承
- python 3.x 的经典类 新式类都按广度优先继承
多态的好处
开闭原则:
开:对扩展功能开,新增一个Pig类 。
闭:对类部代码闭,无需改变方法run,和父类Animal代码。
总:在不改动之前代码的情况下,新增了一个功能
def run(Animal):
Animal.run()
run(cat)
run(Pig())
del析构函数
在示例结尾释放,销毁的时候执行,通常用于做一些结尾工作
class C():
name="domain"
def __init__(self):
pass
def __del__(self):
print("示例释放")
c1=C()
del c1
类的特殊方法
staticmethod 静态方法
在类里面的静态方法,用staticmethod 修饰
class Demo():
@staticmethod
def fun(name):
print(name)
Demo.fun("domain")
classmethod 类方法
在类里面的类方法,用classmethod修饰,只能访问 类变量,不能访问示例变量
class Demo():
name="domain"
def __init__(self,name):
self.name=name
@classmethod
def fun(self):
print(self.name)
d=Demo("alex")
d.fun()
property 类属性方法
property,把一个方法变成一个静态属性调用,用于类属性的get和set
class Demo():
def __init__(self):
# self.name=name
pass
@property
def get_name(self,name): #property get值
return self.name
@get_name.setter #.setter set值
def set_name(self, name):
self.name = name
@get_name.deleter #deleter del值
def del_name(self, name):
del self.name
d=Demo()
d.name="domain"
print(d.name)
print(d.name)
del d.name
doc
输出类描述信息
module
输出当前使用的类是哪个模块里面的
class
输出类本身
call
通过对象的 对象() 调用call方法
class Demo():
def __call__(self, *args, **kwargs):
print(args,kwargs)
d=Demo()
d(1,2,3,4,name='domain',age=1)
dict
class Demo():
def __init__(self):
pass
print(Demo.__dict__) #输出类所有属性
d=Demo()
print(d.__dict__) #输出实例所有属性
str
自定义类对象的输出信息
class Demo():
def __init__(self,name):
self.name=name
def __str__(self):
return "<obj:%s>"%self.name
d=Demo("domain")
print(d)
通过字典的形式给对象赋值
class Demo():
def __init__(self):
self.data={}
def __setitem__(self, key, value): #添加字典元素
self.data[key]=value
def __getitem__(self, key): #获取字典元素
print(self.data[key])
def __delitem__(self, key): #删除字典元素
del self.data[key]
d=Demo()
d['name']='domain'
d['age']=18
print(d['name'])
del d['age']
反射
核心本质其实就是利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
通过四个方法实现 对字符串 映射属性的操作
- hasattr() #对象中是否存在方法或者对象
- getattr() #获取对象中方法或者对象
- setattr() #设置一个对象中的方法或者对象
- delattr() #删除一个对象中方法或者对象
class Demo():
name='alex'
def __init__(self):
pass
d=Demo()
chioce=input("please input a String:") #输入字符串
if hasattr(d,chioce): #判断是否存在属性
print(getattr(d,chioce))
setattr(d,chioce,'domain') #存在属性重新设置
print(getattr(d, chioce))
else:
setattr(d,chioce,'domain') #不存在属性设置一个
chioce=input("please input a String:")
if hasattr(d,chioce):
delattr(d,chioce) #删除存在属性
print(getattr(d,chioce))
```
## 通过反射动态导入包
目录结构
|-- package
| |-- A.py
|-- ClassDemo.Class
|-- function.py #当前运行的py文件
from package import A
print(A.ClassDemo)
A.ClassDemo()
package=import(‘package.A’) #同上
package.A.ClassDemo()
“