Python入门学习笔记————11 (类与对象)
程序员文章站
2022-03-17 12:14:56
...
class Student ():
name = 'goudan'
age = 18
Student.__dict__
goudan = Student()
goudan.__dict__
Out[38]:
{}
类和对象的成员分析
- 类和对象都可以存储成员,成员可以归类所有也可以归对象所有
- 类存储成员时使用的是与类关联的一个对象
- 独享存储成员是存储在当前的对象中
- 对象访问一个成员时,如果对象中没有该成员,尝试访问类中的同名成员,如果对象中有此成员,一定使用对象中的成员
- 创建对象的时候,类中的成员不会放入对象中,而是得到一个空对象,没有成员
- 通过对象对类中成员重新赋值或者通过对象添加成员时,对应成员会保存在对象中,而不会修改类成员
In [33]:
class A ():
name = 'goudan'
age = 18
#注意say的写法,参数有一个self
def say(self):
self.name='aaa'
self.age=20
#此案例说明,类实例的属性和对象的实例属性在不对对象的实例属性赋值的前提下,指向同一个变量
#此时A称为类实例
print(A.name)
print(A.age)
print('#'*20)
print(id(A.name))
print(id(A.age))
print('#'*20)
a = A()
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
goudan 18 #################### 139958490438376 94215097638656 #################### goudan 18 139958490438376 94215097638656
In [39]:
print(A.name)
print(A.age)
print('#'*20)
print(id(A.name))
print(id(A.age))
print('#'*20)
a = A()
#查看A内所有的属性
print(A.__dict__)
print('#'*20)
#赋值前查看属性
print(a.__dict__)
print('#'*20)
#对实例对象赋值并查看属性
a.name = 'pidan'
a.age = 10
print(a.__dict__)
print(a.name)
print(a.age)
print(id(a.name))
print(id(a.age))
goudan 18 #################### 139958490438376 94215097638656 #################### {'__module__': '__main__', 'name': 'goudan', 'age': 18, 'say': <function A.say at 0x7f4aa00b5730>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None} #################### {} #################### {'name': 'pidan', 'age': 10} pidan 10 139958489651832 94215097638400
关于self
- self 在对象方法中表示对象本身,如果通过对象调用一个方法,那么该对象会自动传入到当前方法的第一个参数
- self本身不是关键字,只是一个用于接受对象的普通参数,理论上可以用任何普通变量名代替
- 方法中有self形参的方法成为非绑定类的方法,可以通过对象访问,没有self的绑定类的方法,只能通过类访问
- 使用类访问绑定类的方法时,如果类方法中需要访问当前类的成员,可以通过class成员名来访问
In [44]:
class Student ():
name = 'goudan'
age = 18
#注意say的写法,参数有一个self,self本身不是关键字,可以更换为其他
def Homework(self):
self.name='aaa'
self.age=20
print('my name is {0}'.format(self.name))
print('I am {0} years old'.format(self.age))
goudan = Student()
goudan.Homework()
my name is aaa I am 20 years old
In [56]:
class Teacher ():
name = 'goudan'
age = 18
def say(self):
self.name = 'haha'
self.age = 20
print('my name is {0}'.format(self.name))
print('I am {0} years old'.format(self.age))
#调用类成员时需要使用__class__
print('I am {0} years old'.format(__class__.age))
def good():
#访问类里面的成员
print(__class__.name)
print(__class__.age)
#
print('see you again')
t = Teacher()
t.say()
#调用绑定参数需要使用类名
Teacher.good()
my name is haha I am 20 years old I am 18 years old goudan 18 see you again
In [58]:
# 关于self的案例
class A ():
name = 'goudan'
age = 18
#构造函数
def __init__(self):
self.name = 'aaa'
self.age=20
def say(self):
print(self.name)
print(self.age)
class B ():
name = 'bbb'
age = 30
a = A()
#系统默认传入a
a.say()
#传入参数为a
A.say(a)
##传入参数为A
A.say(A)
#此时传入的是类实例B,因为B具有name和age属性,所以不会报错
A.say(B)
#以上例子使用鸭子模型
aaa 20 aaa 20 goudan 18 bbb 30
面向对象的三大特征
封装
- 封装就是对对象的成员进行访问限制
- 三个级别
- 公开 public
- 受保护的 protected
- 私有的 private
- public,protectde,private不是关键字
- 判别对象位置
- 对象内部
- 对象外部
- 子类中
- 私有
- 私有成员是*的封装,只能在当前类或对象中访问
- 私有成员前添加两个下划线即可 class Person():
#name为公有成员 name = 'haha' #__age为私有成员 __age = 18
- Python的私有不是正的私有,是一种成为name mangling的改名策略,可以使用 .classnameattributename访问 /注意案例
继承
多态
In [60]:
#私有实例
class Person():
#name为公有成员
name = 'haha'
#__age为私有成员
__age = 18
p = Person()
print(p.name)
#注意报错信息
print(p.__age)
haha
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-60-21f97a098560> in <module>() 7 print(p.name) 8 #注意报错信息 ----> 9 print(p.__age) AttributeError: 'Person' object has no attribute '__age'
In [62]:
#name mangling技术
print(Person.__dict__)
{'__module__': '__main__', 'name': 'haha', '_Person__age': 18, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
In [64]:
#注意上述函数运行结果中的age,通过此命令可以访问私有(即被更改命名的)成员
print(p._Person__age)
18