1. self
- 类对象和实例对象都可以保存属性和方法。
如果这个属性或者方法是所有实例所共享的,则应该保存到类对象中。
如果这个属性或者方法是某个实例所独有的,则应该保存到实例对象中。
一般情况下都是保存到实例当中。
# -------------------------------Classroom exercises-------------------------------
class Person: # 创建 Person 类对象
name = 'Sam' # 在类中添加属性
def speak(s): # 再类中添加方法
print('Hello World!')
# 创建Person的实例。
person1 = Person() # 创建person1实例对像
person2 = Person() # 创建person2实例对像
# 修改实例中的属性
person1.name = 'Janice'
person2.name = 'Mike'
print('person1.name = %s \nperson2.name = %s'%(person1.name,person2.name))
'''
结果:
person1.name = Janice
person2.name = Mike
'''
# -------------------------------Classroom exercises-------------------------------
# 需要修改类中的方法
class Person:
name = 'Sam'
def speak(s):
print('Hello World! I am Sam')
person1 = Person()
person2 = Person()
person1.name = 'Janice' # 实例中添加属性
person2.name = 'Mike' # 实例中添加属性
person1.speak() # Hello World! I am Sam
person2.speak() # Hello World! I am Sam
# --------------------------------------Part 1--------------------------------------
# 如今需要修改类中的方法,直接修改类中的名字
class Person:
name = 'Sam'
def speak(s):
print('Hello World! I am Janice')
person1 = Person()
person2 = Person()
person1.name = 'Janice' # 实例中添加属性
person2.name = 'Mike' # 实例中添加属性
person1.speak() # Hello World! I am Janice
person2.speak() # Hello World! I am Janice
# 你会发现person1.speak()和person2.speak()结果一样,原因类中的方法已经固定了。
# --------------------------------------Part 2--------------------------------------
class Person:
name = 'Sam'
def speak(s):
print('Hello World! I am %s'%'Janice')
person1 = Person()
person2 = Person()
person1.name = 'Janice' # 实例中添加属性
person2.name = 'Mike' # 实例中添加属性
person1.speak() # Hello World! I am Janice
person2.speak() # Hello World! I am Janice
# 同样你会发现person1.speak()和person2.speak()结果一样,原因类中的方法已经固定了。
# --------------------------------------Part 3-------------------------------------
#直接调用类中的属性。
class Person:
name = 'Sam'
def speak(s):
print('Hello World! I am %s'%name)
person1 = Person()
person2 = Person()
person1.name = 'Janice' # 实例中添加属性
person2.name = 'Mike' # 实例中添加属性
person1.speak()
person2.speak()
'''
print('Hello World! I am %s'%name)
NameError: name 'name' is not defined
'''
# 在类和闭包原理是不同,属性name,方法内部是寻找不到的。
# --------------------------------------Part 4-------------------------------------
#直接调用类中的属性。
class Person:
name = 'Sam'
def speak(s):
print('Hello World! I am %s'%name)
person1 = Person()
person2 = Person()
person1.name = 'Janice' # 实例中添加属性
person2.name = 'Mike' # 实例中添加属性
person1.speak()
person2.speak()
# 方法每次调用时解析器都会自动传递一个实参
# --------------------------------------Part 5-------------------------------------
class Person:
name = 'Sam'
def speak(s):
print(s)
person1 = Person()
person2 = Person()
person1.name = 'Janice' # 实例中添加属性
person2.name = 'Mike' # 实例中添加属性
person1.speak() # <__main__.Person object at 0x0000000002F710F0>
person2.speak() # <__main__.Person object at 0x0000000002F71080>
# 证明s为一个对象
print(person1) # <__main__.Person object at 0x0000000002F710F0>
print(person2) # <__main__.Person object at 0x0000000002F71080>
# 由此可见 person1.speak和print(person1)打印的都是同一个对象
'''
方法每次调用时,解析器都会自动传递一个实参。
如果是person1调用,则第一个参数就是person1对象。
如果是person2调用,则第一个参数就是person2对象。
一般我们都会将这个参数命名为 self,这就是self 的来历。
'''
# --------------------------------------Part 6-------------------------------------
# 故程序为:
class Person:
name = 'Sam'
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person()
person2 = Person()
person1.name = 'Janice' # 实例中添加属性
person2.name = 'Mike' # 实例中添加属性
person1.speak() # Hello World! I am Janice
person2.speak() # Hello World! I am Mike
总结:
在类和闭包原理是不同,方法内部是寻找不到类中的属性。
2. 特殊方法
# -------------------------------Classroom exercises-------------------------------
class Person: # 创建 Person 类对象
name = 'Sam'
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person()
person2 = Person()
person2.speak() # Hello World! I am Sam
# --------------------------------------Part 1--------------------------------------
# 若果类中没有属性,则会报错
class Person:
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person()
person2 = Person()
person2.speak()
'''
print('Hello World! I am %s'%self.name)
AttributeError: 'Person' object has no attribute 'name'
''' # 报错
# --------------------------------------Part 2--------------------------------------
# 手动输入
class Person:
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person()
person2 = Person()
person2.name = 'Sam' # 给实例对象person2中添加属性name
person2.speak() # Hello World! I am Sam
# 添加新实例person3
person3 = Person()
person3.speak()
'''
print('Hello World! I am %s'%self.name)
AttributeError: 'Person' object has no attribute 'name'
''' # 添加新的实例对象person3中,由于类中没有name,就会报错。
# 同样也证明上面person2.name = 'Sam'只是添加到实例对象 person2 中去。
# 所以要在person3.speak()上要添加代码 person3.name = 'John',在实例对象person3中添加属性。
# --------------------------------------Part 3--------------------------------------
'''
综上可知,已经有不少问题了
1.name属性是必须的。
即 类中不添加 name 属性时,实例化对象person2,直接调用方法 speak(),就会报错。
2.name属性是不同的。
即 实例化对象 person2.name = 'Sam' ; person3.name = 'John'。
两个name的值是不相同的
3.实例化对象的时候容易出错。
即 类中没有name属性,person3 也没有那么属性的时候
创建 person3 = Person() 代码,容易出错
'''
# --------------------------------------Part 4--------------------------------------
'''
为了解决以上问题
我们现在用到特殊方法了。
首先在类中可以定一些特殊方法(魔术方法)
特殊方法: __方法__结尾
'''
class Person:
def __init__(self): # 创建特殊方法
print('Hello World')
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person() # Hello World
person1.__init__() # Hello World
# 返回两个Hello, 证明特殊方法不需要自己调用。
# 创建新的实例会对象,都会返回相同的,也都是直接调用了特殊方法。
person2 = Person() # Hello World
person3 = Person() # Hello World
person4 = Person() # Hello World
person5 = Person() # Hello World
'''
证明
创建一个特殊方法,新的实例化对象会直接调用。
'''
# --------------------------------------Part 5--------------------------------------
class Person:
def __init__(self): # 创建特殊方法
print(self)
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person() # <__main__.Person object at 0x0000000002F710F0>
person2 = Person() # <__main__.Person object at 0x0000000002F71D30>
person3 = Person() # <__main__.Person object at 0x0000000002F71B38>
# 发现通过 self 向新创建的实例对象中初始化属性。
# --------------------------------------Part 6--------------------------------------
class Person:
def __init__(self): # 创建特殊方法
self.name = 'Sam'
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person()
person2 = Person()
person3 = Person()
person1.speak() # Hello World! I am Sam
person2.speak() # Hello World! I am Sam
person3.speak() # Hello World! I am Sam
# 但是内容又被写死了。
# --------------------------------------Part 7--------------------------------------
# 在特殊方法中添加形参。
class Person:
def __init__(self, name): # 创建特殊方法
self.name = name
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person()
person2 = Person()
person3 = Person()
person1.speak()
person2.speak()
person3.speak()
'''
person1 = Person()
TypeError: __init__() missing 1 required positional argument: 'name'
'''# 报错 name 缺少参数
# --------------------------------------Part 8--------------------------------------
# 添加参数
class Person:
def __init__(self, name): # 创建特殊方法
self.name = name
def speak(self):
print('Hello World! I am %s'%self.name)
person1 = Person('Sam')
person2 = Person('Janice')
person3 = Person('Mike')
person1.speak() # Hello World! I am Sam
person2.speak() # Hello World! I am Janice
person3.speak() # Hello World! I am Mike
'''
类的基本结构
class 类名([父类]):
公共属性...
# 对象初始化方法
def __init(self, .....):
...
# 其他方法
def method1(self):
...
'''
'''
注意不能在特殊方法中添加方法,由于特殊方法用来初始化属性的,所以不能嵌套方法
'''
不断完善,再接再厉。