**
1,dir()函数可以获得对象的 所有 属性和方法 包含自定义的属性和方法
**
class Person:
def test1(self):
print("来呀快活呀")
def test2(self):
print("一边玩去")
n = object() # object基类创建的对象
i = Person() # Person类创建的对象
print(dir(n))
print(dir(i))
运行结果如下
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'test1', 'test2']
以上可以看出:test1 和 test2 方法显示在第二行的打印结果里面
test1和test2虽然定义的是方法,实际上方法也是属性,只不过属性的类型是"method" say_age<class “method” >
**
2,‘obj__dict__’ 只获取自定义的一些属性
**
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def test1(self):
print("来呀快活呀")
def test2(self):
print("滚一边去")
i = Person("小二", 17)
print(dir(i))
print(i.__dict__)
运行结果如下:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name', 'test1', 'test2']
{'name': '小二', 'age': 17}
**
3,isinstance 判断对象是不是属于某一个类的实例对象
**
class Life:
pass
class Person:
pass
i = Person()
print(isinstance(i, Person))
print(isinstance(i, Life))
运行结果如下:
True
False
**
4,类对象
**
当python解释器执行class语句时,就会自动创建一个类对象
class Student:
pass
print(id(Student))
print(type(Student))
运行结果为:
2468217837064
<class 'type'> # Student这个类对象就是type下的一个实例对象
验证过程如下所示:
class Student:
pass
print(id(Student))
print(type(Student))
Stu2 = Student # Student这个对象可以重新赋值给新的变量 Stu2 , 进而实现相关的调用
s1 = Stu2()
print(s1)
运行结果如下:
1748392130296
<class 'type'>
<__main__.Student object at 0x000001971637C080>
**
5,类属性
**
类既然也是对象,那么类也拥有类属性和类对象
可通过赋值语句定义类属性
class Student:
company = "爱的魔力" #类属性
count = 0 #类属性
def __init__(self, name, score): #实例属性
self.name = name
self.score = score
Student.count += 1 #使用 类名.点的方式访问类属性
def say_score(self): #实例方法
print("公司是%s" % Student.company)
print("{0}的分数是{1}".format(self.name, self.score))
s1 = Student("小二", 59) #s1实例对象 自动调用init初始化方法
s2 = Student("小三", 58)
s3 = Student("小五", 60)
s1.say_score()
s2.say_score()
s3.say_score()
print("一共创建了{0}个student对象".format(Student.count))
运行结果如下:
公司是爱的魔力
小二的分数是59
公司是爱的魔力
小三的分数是58
公司是爱的魔力
小五的分数是60
一共创建了3个student对象
**
6,类方法
**
class Student:
company = "XXX"
count = 0
@classmethod
def print_company(cls):
print(cls.company)
Student.print_company()
输出结果为:
XXX
**
7,静态方法 在类中定义与类对象无关的方法 既不访问类属性也不访问实例属性
**
class Dog(object):
@staticmethod
def run():
print("狗在跑...")
Dog.run() # 通过 类名. 调用静态方法 不需要创建对象,直接调用
**
8,__call__方法,定义了__call__方法的对象,成为“可调用对象”。即该对象可以像函数一样被调用
**
class SalaryAccount:
def __call__(self, salary):
print("领工资啦")
year_salary = salary * 12
day_salary = salary // 22.5
hour_salary = day_salary // 8
return dict(year_salary=year_salary, month_salary=salary, day_salary=day_salary, hour_salary=hour_salary)
s = SalaryAccount()
print(s(5000))
运行结果如下:
领工资啦
{'year_salary': 60000, 'month_salary': 5000, 'day_salary': 222.0, 'hour_salary': 27.0}
**
9,可重写object中的__str__方法 此方法返回的是对“对象的描述” 可帮助查看对象的信息
**
没有重新str方法时打印的信息如下:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("小二", 18)
print(p)
<__main__.Person object at 0x000002329E57C080>
重新str方法后,打印的结果如下:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "名字是{0}年龄是{1}".format(self.name, self.age)
p = Person("小二", 18)
print(p)
名字是小二年龄是18
**
10,MRO函数 method resolution order 方法解析顺序 可通过mro()函数获得类的解析顺序
**
class A:
def say(self):
print("AAA")
class B:
def say(self):
print("BBB")
class C(B, A):
pass
c1 = C()
c1.say()
print(C.mro())
运行结果如下:
BBB
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
**
11,super()调用父类的方法
**
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def say_name(self):
print("我是",self.name)
class Student(Person):
def __init__(self,name,age,score):
self.score = score
Person.__init__(self,name,age) #类名.点的方式调用父类中的初始化方法 python解释器不会主动调用
def say_score(self):
print(self.name,"分数是:",self.score)
super().say_name() #super()点的方式调用父类中的方法
s1 = Student("张三", 15, 85)
s1.say_score()
运行结果如下:
张三 分数是: 85
我是 张三
**
12,多态
**
1,多态是方法的多态,属性没有多态
2,多态的存在有两个必要条件:继承和方法重写
class Man:
def eat(self):
print("饿了,吃饭了")
class ChineseMan(Man):
def eat(self):
print("中国人用筷子吃饭")
class EnglishMan(Man):
def eat(self):
print("英国人用叉子吃饭")
class IndianMan(Man):
def eat(self):
print("印度人用右手吃饭")
def man_eat(m):
if isinstance(m,Man):
m.eat() #不同的对象调用不同的方法
else:
print("不知道哪国人")
man_eat(ChineseMan())
man_eat(EnglishMan())
man_eat(IndianMan())
运行结果如下:
中国人用筷子吃饭
英国人用叉子吃饭
印度人用右手吃饭
**
13,特殊方法 运算符方法
**
可重写上面的运算符方法,即实现了“运算符的重载”
class Person:
def __init__(self, name):
self.name = name
def __add__(self, other):
if isinstance(other, Person):
return "{0}--{1}".format(self.name, other.name)
else:
return "不是同类对象,不能相加"
def __mul__(self, other):
if isinstance(other, int):
return self.name * other
else:
return "不是同类对象,不能相乘"
p1 = Person("小二")
p2 = Person("小三")
x = p1 + p2
print(x)
print(p1 * 3)
运行结果如下:
小二--小三
小二小二小二
**
14,特殊属性
**
class A:
pass
class B:
pass
class C(B, A):
def __init__(self, nn):
self.nn = nn
def cc(self):
print("cc")
c = C(3)
print(dir(c))
print(c.__dict__)
print(c.__class__)
print(C.__bases__)
print(C.mro())
print(A.__subclasses__())
运算结果如下:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'cc', 'nn']
{'nn': 3}
<class '__main__.C'>
(<class '__main__.B'>, <class '__main__.A'>)
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
[<class '__main__.C'>]