python学习日记3-面向对象
面向对象
++++++++++++++++++++++++++++++++++
总结目录:
一. 属性与方法
1. 类属性 @property
2. 实例属性
3. 类方法 @classmethod
4. 实例方法
5. 静态方法 @staticmethod
二. 模块 模块的引用与使用:
import xxx 引用xxx模块
import xxx as new_xxx 引用xxx模块,并以new_xxx为别名
from xxx import yyy 从xxx模块引用yyy 属性或者方法或者变量
from xxx import * 从xxx模块引用 所有的属性和方法和变量
from xxx import yyy as new_yyy 从xxx模块引用yyy 并以new_yyy为别名
三 . 列表推导式 :[ 表达式 for 变量 in 旧列表 if 条件]
四 .生成器:
创建方式:
第一种方法:把列表推导式的[] 修改().例如:(表达式 for 变量 in 旧列表 if 条件);
第二种方法为通过函数+ yield 的方式。
读取: 通过next(生成器实例) 的方式读取数据
1. 基础
类是type类型的一个对象
class Myclass():
# 方法至少需要一个参数
def speak(self):
print('speak')
pass
print(id(Myclass),type(Myclass))
# 140520792804736 <class 'type'> 类型为type
mc = Myclass()
print(id(mc),type(mc))
# 输出:4482600272 <class '__main__.Myclass'> 类型为Myclass
2.self 参数
- 类内部的方法不能直接访问类内部的变量,只能通过“self.属性”的方式访问,并且self 在这里会被指代为类的具体实例。
class Myclass():
name = '老高'
# 方法至少需要一个参数,第一个参数指向为实力本身。
def speak(self):
print('%s speak'%self.name)
pass
mc = Myclass()
mc.speak();
mc2 = Myclass()
mc2.name = '高子怡'
mc2.speak()
3. 类的特殊方法,使用开始 结束的函数,
- 在类中的特殊方法,又称为魔术方法。
- 一般是以__xx__() 形式出现的。
- 特殊方法一般都是自动调用的,不需要手动调用的
class Person:
print('sdsd') # 现执行print('sdsd') ,后执行__init__
def __init__(self,name):
print('init 执行')
self.hidden_name = name
-
其他常用的特殊方法:
a > __repr__ 和 __str__ - 字符串表示形式
__repr__ 用于提供给开发者查看的对象字符串表示,而 __str__ 用于提供给用户的对象字符串表示
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f'Point({self.x}, {self.y})'
def __str__(self):
return f'({self.x}, {self.y})'
point = Point(3, 4)
print(repr(point)) # 输出结果为 'Point(3, 4)'
print(str(point)) # 输出结果为 '(3, 4)'
b > __len__ 获取对象长度
定义对象的长度,使其支持内置函数 len()
class CustomList:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
my_list = CustomList([1, 2, 3, 4, 5])
print(len(my_list)) # 输出结果为 5
c > __eq__ 比较相等性
定义对象之间的相等性比较
class Book:
def __init__(self, title, author):
self.title = title
self.author = author
def __eq__(self, other):
return self.title == other.title and self.author == other.author
book1 = Book('Python', 'Guido')
book2 = Book('Python', 'Guido')
print(book1 == book2) # 输出结果为 True
d > __iter__ 和 __next__ 迭代器
实现对象的迭代器协议,用于迭代对象。
class Countdown:
def __init__(self, start):
self.start = start
def __iter__(self):
self.current = self.start
return self
def __next__(self):
if self.current <= 0:
raise StopIteration
# raise 手动触发异常的关键字
#StopIteration一个内置异常类,通常与迭代器(iterator)和生成器(generator)一起使用。在迭代过程中,当没有更多的元素可供迭代时,Python 的迭代器会引发 StopIteration 异常来通知迭代结束
else:
result = self.current
self.current -= 1
return result
countdown = Countdown(5)
for num in countdown:
print(num) # 输出倒数 5, 4, 3, 2, 1
4. 类的封装
- 需要封装的原因:增强数据的安全性,不能使其随便的更改。
- 封装是指隐藏类中的一些不希望被外部访问的属性和方法。
- 封装的属性一般通过getter() 和setter()的方式对其进行访问和修改
- 隐藏属性真正的方式:一般是需要使用xxx 双下划线的方式,使用双下划线后,python默认会修改属性的名字,使其在外部访问不到。***修改规则为:类名_属性名***
- 但在实际应用中,我们一般使用单下划线_xx的方式定义私有属性
class Person:
def __init__(self,name,age):
self.__name = name
# 在实际应用中,一般使用这种方式保持私有属性。其目的在于告知其他开发者,这是一个私有属性
self._age = age
def get_name(self):
return self.__name
def set_name(self,name):
self.__name = name
def sperk(self):
print("我的名字叫: %s"%self.get_name())
#
# age属性的getter和setter 存取器
def get_age(self):
return self._age
def set_age(self, age):
self._age = age
p = Person('laogao')
p.sperk()
print(p._Person__name)
# 输出为:laogao。也就是说在使用__xxx 双下划线的方式隐藏属性时,其实质是:python将其属性名称修改为了_类名__属性名***,即_Person__name
5. property 装饰器
@property装饰器 : 我们可以使用@property装饰器来创建只读属性。
@property 装饰器原理:会将方法转化为相同名称的只读属性。可以与所定义的属性配合使用,这样可以有效的防止属性被修改。
class Person:
def __init__(self,name,age):
self._name = name
self._age = age
#@property 将方法转化为相同名称的只读属性
@property
def name(self):
return self._name
#这是一个setter方法,setter方法的装饰器格式为:@属性名.setter
# 一般很少使用
@name.setter
def name(self,name):
self._name = name
p = Person('laogao', 40)
p.name = '你哈'
print(p.name)
@classmethod 装饰器,可以是类中的方法直接变成为类方法,而非实例方法。
实例方法与类方法的转换:p.test() 与Person.test(p) 是一样的.
class Person():
total = 0
def __init__(self,name):
# 注意类属性的时候,需要赋值给 Person.属性
Person.total += 1
# classmethod 可以是方法变为类方法,可以直接使用类名调用改方法
@classmethod
def getTotal(self):
print('当前一共 %s 个人'%self.total)
return
# 实例方法
def test(self):
print('实例方法test')
p = Person('laogao')
p2 = Person('gaotui')
# 该处是 使用的类的方法 直接调用的
Person.getTotal()
#输出 当前一共 2 个人
#其实我尝试了一下,使用实例也是可以调用的
p2.getTotal()
#输出 当前一共 2 个人
# 实例方法与类方法的转换
p.test() 与Person.test(p) 是一样的。
@staticmethod 用于定义静态方法的装饰器
静态方法是类中的一个方法,与类和实例无关,它不会自动传递类或实例作为第一个参数。静态方法在逻辑上属于类,但在定义时不需要指定 self 或 cls 参数。
一般用于做一些工具类使用比较多。
class MathOperations:
@staticmethod
def add(a, b):
return a + b
@staticmethod
def multiply(a, b):
return a * b
# 通过类直接调用静态方法
print(MathOperations.add(5, 3)) # 输出结果为 8
print(MathOperations.multiply(5, 3)) # 输出结果为 15
# 通过类的实例调用静态方法
math = MathOperations()
print(math.add(2, 2)) # 输出结果为 4
print(math.multiply(2, 2)) # 输出结果为 4
6. 继承与多重继承
- 使用继承的方式,提高类的复用性(基类,超类)
- super()获取当前类的父类,调用是不需要self参数
- 多重继承:是指一个子类可以继承多个父类的属性和方法。
方式为: 在类名的()内添加多个父类,多父类中同名的方法,按照第一父类,第二父类依次向上寻找。前面的覆盖后面的但是 python接收多重继承。 一般很少使用,使用时会程序更加复杂化。
class A:
def some_method(self):
print("Method from class A")
# 继承,
class B(A):
def __init__(self,name,age):
# super()获取当前类的父类,调用是不需要self参数
super().__init__(name)
self._age = age
def some_method(self):
super().some_method() # 调用 A 类的 some_method()
print("Method from class B")
class C(A):
def some_method(self):
print("Method from class C")
# 多重继承
class D(B, C):
def some_method(self):
super(B,self).some_method() # 调用 B 类的 some_method()
print("Method from class D")
6. 多态 即多种形态
譬如:内置方法len(),就是多态。不管输入的是list类型还是字符串类型。都可以输出正确的长度。
lst = [1,2,3]
print(len(lst))
# 输出:2
str = 'python'
print(len(str))
# 输出:6