好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 Solowang 于 2024-7-15 11:12 编辑
我是个新手 在学习的道路上发现基础没有打好 没办法那就补充基础知识 一、类方法和静态方法定义:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);调用:实例对象和类对象都可以调用。原则上,类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法。如下场景:假设我有一个学生类和一个班级类,想要实现的功能为:
执行班级人数增加的操作、获得班级的总人数;
学生类继承自班级类,每实例化一个学生,班级人数都能增加;
最后,我想定义一些学生,获得班级中的总人数。
[Python] 纯文本查看 复制代码 class ClassTest(object):
__num = 0
@classmethod
def addNum(cls):
cls.__num += 1
@classmethod
def getNum(cls):
return cls.__num
# 这里我用到魔术函数__new__,主要是为了在创建实例的时候调用人数累加的函数。
def __new__(self):
ClassTest.addNum()
return super(ClassTest, self).__new__(self)
class Student(ClassTest):
def __init__(self):
self.name = ''
a = Student()
b = Student()
print(ClassTest.getNum()) )
使用装饰器@staticmethod。静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。譬如,我想定义一个关于时间操作的类,其中有一个获取当前时间的函数。[Python] 纯文本查看 复制代码 import time
class TimeTest(object):
def __init__(self, hour, minute, second):
self.hour = hour
self.minute = minute
self.second = second
@staticmethod
def showTime():
return time.strftime("%H:%M:%S", time.localtime())
print(TimeTest.showTime())
t = TimeTest(2, 10, 10)
nowTime = t.showTime()
print(nowTime)
二、私有属性和私有方法在Python中,如果你想定义一个私有函数,你可以在函数名称前加上两个下划线__。这会触发一个名字改编(name mangling)的过程,使得这个函数在外部不容易被直接访问。这种机制的目的是为了“伪私有”,实际上是提供了一种弱保护措施来避免子类意外覆盖基类的方法。Python对于类的成员没有严格的访问控制限制,这与其他面向对象 语言有区别。关于私有属性和私有方法,有如下要点: - 1 通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public)。
- 2 类内部可以访问私有属性(方法)
- 3 类外部不能直接访问私有属性(方法)
- 4 类外部可以通过 _类名__私有属性(方法)名 ”访问私有属性(方法)
[Python] 纯文本查看 复制代码 #测试私有属性、私有方法
class Employee:
__company = "百战程序员" #私有.通过dir查到_Employee__company
def __init__(self,name,age):
self.name = name
self.__age = age#私有实例属性
def say_company(self):
print("我的公司是:",Employee.__company)
print(self.name,"的年龄 是:",self.__age)
self.__work()
def __work(self): #私有实例方法,通过dir可查
print("工作!好好工作,好好赚钱,娶个媳妇!")
p1 = Employee("高淇",32)
print(p1.name)
print(dir(p1))
p1.say_company()
print(p1._Employee__age)#通过这种方式进行调用
--------------------------------------------------------
高淇
['_Employee__age', '_Employee__company', '_Employee__work', '__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__', 'name', 'say_company']
我的公司是: 百战程序员
高淇 的年龄 是: 32
工作!好好工作,好好赚钱,娶个媳妇!
32
三、装饰器@property@property 可以将一个方法的调用方式变成“属性调用”。 @property 主要用于帮助我们处理属性的读操作、写操作。对于某一个 属性,我们可以直接通过: emp1.salary = 30000使用场景:如上的操作读操作、写操作。但是,这种做法不安全。比如,我需 要限制薪水必须为 1-10000 的数字。这时候,我们就需要通过使用装 饰器 @property 来处理。[Python] 纯文本查看 复制代码 class Person:
def __init__(self, name, age):
self._name = name # 使用下划线前缀表示私有变量
self._age = age
@property
def name(self):
"""获取name属性的值"""
return self._name
@name.setter
def name(self, value):
"""设置name属性的值"""
if not isinstance(value, str):
raise ValueError("name must be a string")
self._name = value
@property
def age(self):
"""获取age属性的值"""
return self._age
@age.setter
def age(self, value):
"""设置age属性的值"""
if not isinstance(value, int) or value < 0:
raise ValueError("age must be a non-negative integer")
self._age = value
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
# 使用示例
p = Person("Alice", 25)
print(p) # 输出:Person(name=Alice, age=25)
p.name = "Bob" # 修改name属性的值
print(p) # 输出:Person(name=Bob, age=25)
#
# p.age = 30 # 修改age属性的值
# print(p) # 输出:Person(name=Bob, age=30)
# # 尝试设置非法值
# p.name = 123 # 抛出ValueError异常:name must be a string
# p.age = -1 # 抛出ValueError异常:age must be a non-negative integer
-----------------------------------------------------------------
Person(name=Alice, age=25)
Person(name=Bob, age=25)
属性和方法命名:1、_xxx :保护成员,不能用 from module import * 导入,只有类对象和子类对象能访问这些成员。(⚠️讲完模块再看)2、__xxx__ :系统定义的特殊成员 3、__xxx : 类中的私有成员,只有类对象自己能访问,子类对象也不能访问。(但,在类外部可以通过 对象名. _类名__xxx 这种特殊方式访问。Python不存在严格意义的私有成员)⚠️再次强调,方法和属性都遵循上面的规则。
四、关于None判断和总结None的解释⚠️None不是False,None不是0,None不是空字符串。None 和任何其他的数据类型比较永远返回False。
五、继承【重点】继承是面向对象三大特征之一。继承不是让我们去新发明、而是去改善。继承逻辑
[Python] 纯文本查看 复制代码 #Python支持多重继承,一个子类可以继承多个父类。继承的语法格式如下:
class 子类类名(父类1[,父类2,...]):
类体
如果在类定义中没有指定父类,则默认父类是 object类 。也就是说, object 是所有类的父类,里面定义了一些所有类共有
的默认实现,比如: __new__()
1 子类不重写 __init__ ,实例化子类时,会自动调用父类定义的 __init__ 。 2 子类重写了 __init__ 时,实例化子类,就不会调用父类已经定义的 __init__ 3 如果重写了 __init__ 时,要使用父类的构造方法,可以使用 super 关键字,也可以使用如下格式调用
[Python] 纯文本查看 复制代码 class person:
def __init__(self,name,age,address):
self.name = name
self.age = age
self.address =address
def say_age(self):
print(self.name,"的年龄是:",self.age)
class xiaoming(person):
def __init__(self,name,age,address,gender):
print("xiaoming的构造方法")
person.__init__(self,name,age,address) #使用基类的方法进行优化,但是需要注意的是这里也要传self
self.gender = gender
xm=xiaoming("小明",12,"辽宁","男")
xm.say_age()
【super】我们都知道,在子类中如果有与父类同名的成员,那就会覆盖掉父类里的成员。那如果你想强制调用父类的成员呢?使用super()函数!这是一个非常重要的函数,最常见的就是通过super调用父类的实例化方法__init__!语法:super(子类名, self).方法名(),需要传入的是子类名和self,调用的是父类里的方法,按父类的方法需要传入参数。[Python] 纯文本查看 复制代码 class A:
def __init__(self, name):
self.name = name
print("父类的__init__方法被执行了!")
def show(self):
print("父类的show方法被执行了!")
class B(A):
def __init__(self, name, age):
super(B, self).__init__(name=name)
self.age = age
def show(self):
super(B, self).show()
obj = B("jack", 18)
obj.show()
六、类成员的继承和重写成员继承:子类继承了父类除构造方法之外的所有成员。 ⚠️(私有属性、私有方法也被继承) 2 方法重写:子类可以重新定义父类中的方法,这样就会覆盖父类 的方法,也称为“重写”
[Python] 纯文本查看 复制代码 # 定义一个父类
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
raise NotImplementedError("子类必须实现这个方法")
# 定义一个子类,继承自Animal类
class Dog(Animal):
def speak(self):
return f"{self.name} says: Woof!"
# 定义另一个子类,也继承自Animal类
class Cat(Animal):
def speak(self):
return f"{self.name} says: Meow!"
# 使用子类
dog = Dog("Buddy")
cat = Cat("Whiskers")
# 调用speak方法,演示方法重写的效果
print(dog.speak()) # 输出: Buddy says: Woof!
[color=#333333]print(cat.speak()) # 输出: Whiskers says: Meow!
多态
多态(polymorphism)是指同一个方法调用由于对象不同可能会 产生不同的行为。 比如:现实生活中,同一个方法,具体实现会完全不同。 比 如:同样是调用人“吃饭”的方法,中国人用筷子吃饭,英国人用 刀叉吃饭,印度人用手吃饭。 关于多态要注意以下2点: 1 多态是方法的多态,属性没有多态。 2 多态的存在有2个必要条件:继承、方法重写 [Python] 纯文本查看 复制代码 class Animal():
def sout(self):
print("动物叫了一下!")
class Dog(Animal):
def sout(self):
print("狗叫了一下!")
class cat(Animal):
def sout(self):
print("猫叫了一下!")
def common_animals(ami):
ami.sout()
common_animals(Dog())
common_animals(cat())
--------------------------------
狗叫了一下!
猫叫了一下!
四、浅拷贝与深拷贝浅拷贝和深拷贝的区别是:浅拷贝只拷贝当前对象不会拷贝到当前对象的子对象,深拷贝是会拷贝当前的对象以及子对象[Python] 纯文本查看 复制代码 import copy
class MobilePhone:
def __init__(self, cpu):
self.cpu = cpu
class CPU:
pass
# 创建CPU对象
c = CPU()
# 创建MobilePhone对象,并将CPU对象作为参数传递
m = MobilePhone(c)
# 打印原始对象的ID
print("----浅拷贝-------")
m2 = copy.copy(m) # m2是新拷贝的另一个手机对象
print("m:", id(m))
print("m2:", id(m2))
print("m的cpu:", id(m.cpu))
print("m2的cpu:", id(m2.cpu)) # m2和m拥有了一样的cpu对象
# m: 1452501984496
# m2: 1452503257776
# m的cpu: 1452501985216
# m2的cpu: 1452501985216
# 打印深拷贝后对象的ID
print("----深拷贝--------")
m3 = copy.deepcopy(m)
print("m:", id(m))
print("m3:", id(m3))
print("m的cpu:", id(m.cpu))
print("m3的cpu:", id(m3.cpu)) # m
#----深拷贝--------
# m: 1452501984496
# m3: 1452503202160
# m的cpu: 1452501985216
# m3的cpu: 1452503654064
四、抽象类
抽象基类是Python中一种强大的工具,用于定义接口和规范,并确保类遵循指定的约定。它们在代码的类型检查、文档编写和设计模式实现中发挥着重要作用。本文详细介绍了抽象基类的概念、创建方法和应用场景,并提供了丰富的示例代码,希望可以帮助大家更好地理解和应用Python中的抽象基类。通过使用抽象基类,可以编写更加可靠、清晰和可维护的Python代码。[Python] 纯文本查看 复制代码 # python
# -*- coding: utf-8 -*-
# @Time : 2024/6/24
# @Author : solowang
# @Software: PyCharm
# @File : 工厂模式.py
# @desc :
from abc import ABCMeta, abstractmethod
# 创建Animal抽象类 ABCmeta是抽象类继承元类 [*]
class Animal(metaclass=ABCMeta):
@abstractmethod
def do_say(self):
pass
# 创建Dog类
class Dog(Animal):
def do_say(self):
print('Bhow Bhow!')
# 创建Cat类
class Cat(Animal):
def do_say(self):
print('Meow Meow!')
# 创建工厂类
class ForestFactory:
def make_sound(self, object_type):
return eval(object_type)().do_say()
if __name__ == '__main__':
ff = ForestFactory()
ff.make_sound('Cat') |
免费评分
-
查看全部评分
|