面向对象初级

     面向对象初级:

    1.面向对象三大特征:封装  继承   多态    self含义:  指向实例对象本身,让实例能够访问类中的属性和方法

    2.类和对象的创建:    

类和对象的创建(登录注册功能)
class User:
    def __init__(self,name,pwd):
        self.name = name
        self.pwd = pwd

class User_Mannager():
    def __init__(self):
        self.user_list = []#存放User类对象
    def regist(self):
        """
        用户注册
        """
        while True:
            name = input('输入用户名N(退出):')
            if name.upper() == 'N':
                break
            for item in self.user_list:
                if item.name == name:
                    print('用户名已存在,重新输入')
                    flag = True
                    break
            else:
                pwd = input('输入密码:')
                self.user_list.append(User(name,pwd))
                print('注册成功')
                return
            continue
    def Login(self):
        """
        用户登录
        """
        while True:
            name = input('输入用户名:')
            pwd = input('输入密码:')
            for i in self.user_list:
                if i.name == name and i.pwd == pwd:
                    print('登录成功')
                    return
            else:
                print('用户名密码错误')
                continue

    def run(self):
        """
        程序入口
        """
        while True:
            func_dict = {'1':self.Login,'2':self.regist}
            print('界面(N退出):1【登录】2.【注册】')
            num = input('输入:')
            if num.upper() == 'N':
                return
            func = func_dict.get(num)
            if func:
                func()
            else:
                print('输入错误')

if __name__ == "__main__":
    obj = User_Mannager()
    obj.run()

属性:对象具有的特征叫属性

    设置和获取对象具有的属性:

      1,静态  类中:  对象.属性=值    

             外部:  设置:obj = Foo(属性的值)

                  获取:对象.属性  

      2,动态(反射):以字符串的形式去设置获取对象属性  类中:对象.属性=值或者pass  

                                外部:setattr:新增此对象的属性及值或者修改此对象已经具有的属性的值    

                                   格式:setattr(对象   ,属性   (字符串形式),值   (任意类型))

                                   getattr:获取对象已经具有的属性(函数、类、变量)                

                                   格式:getattr(对象,属性  (字符串形式),默认值(属性不存在时返回,任意类型)

                                   delattr:删除对象属性

                                   格式:delattr(对象,属性)

                                   hasattr:检查对象是否有某个属性,返回布尔类型

                                   格式:hasattr(对象,属性(字符串形式))

属性的设置和获取(静态和动态)
#设置和获取对象的值方法一(静态):
class Foo:
    def __init__(self,n,p):     #给这个类所创建的对象中公有的属性进行值的初始化
        self.name = n
        self.pwd = p
obj = Foo('guohan',123)     #设置对象属性的值(对象属性的值封装到对象中)
print(obj.name)     #获取对象的值
#>>>guohan


#设置和获取对象的值方法二(动态:内置函数):     setattr getattr
class Person:
    # 类属性(也可以通过字符串操作)
    species = "human"
    
    def __init__(self, name, age):
        # 实例属性
        self.name = name
        self.age = age

# 创建实例
p = Person("Alice", 30)

# 1. 检查属性是否存在(hasattr)
print(hasattr(p, "name"))  # True(存在实例属性name)
print(hasattr(p, "gender"))  # False(不存在gender属性)
print(hasattr(Person, "species"))  # True(存在类属性species)


# 2. 获取属性值(getattr)
# 获取实例属性
print(getattr(p, "name"))  # Alice(等价于 p.name)
# 获取类属性
print(getattr(Person, "species"))  # human(等价于 Person.species)
# 获取不存在的属性,指定默认值
print(getattr(p, "gender", "unknown"))  # unknown(避免报错)


# 3. 设置属性值(setattr)
# 修改已有实例属性
setattr(p, "age", 31)
print(p.age)  # 31(等价于 p.age = 31)

# 新增实例属性
setattr(p, "gender", "female")
print(p.gender)  # female(动态新增属性)

# 修改类属性
setattr(Person, "species", "Homo sapiens")
print(Person.species)  # Homo sapiens(等价于 Person.species = ...)


# 4. 删除属性(delattr)
# 删除实例属性
delattr(p, "gender")
# print(p.gender)  # 报错:AttributeError(已删除)

# 删除类属性
delattr(Person, "species")
# print(Person.species)  # 报错:AttributeError(已删除)

    

 

 

  impor_module和反射结合:19-13 反射:import_module与反射的结合_哔哩哔哩_bilibili

 

import_modulePython importlib 模块的函数)与反射结合,核心作用是在运行时动态加载模块,并通过字符串形式操作该模块内的属性(如函数、类、变量),无需在代码中硬编码导入路径和属性名。

核心原理与步骤

  1. 动态加载模块:用 import_module("模块路径") 替代 import 模块,支持通过字符串传入模块名(如从配置文件、用户输入中读取模块路径)。
  2. 反射操作属性:用 getattr(模块对象, "属性名") 等反射函数,通过字符串获取 / 调用模块内的属性,实现 “字符串 → 代码元素” 的动态映射。

 

image

  1. 首先,path 是像 "handler.email.Email" 这样的字符串,通过 split 把它分成模块部分(m = "handler.email")和类名字符串(c = "Email")。
  2. 然后用 import_module(m) 导入模块(比如导入 handler.email 这个模块),但此时 c 还是字符串 "Email",不是模块里的 Email 类本身。
  3. 所以必须用 getattr(module, c),从导入的模块 module 里,根据字符串 c(“Email”),拿到真正的 Email 类对象。
  4. 只有拿到类对象后,才能用 cls()(这里 cls 就是拿到的类对象,比如 Email 类)去创建实例 obj = cls()

 

 

      3.封装:    同一类的方法封装到同一类中    值封装到对象中

            类中的属性和方法:公有(一般都是)  私有(以_开头):类实例化的对象无法直接访问私有成员(属性和方法)

            获取对象中封装的所有值

对象.__dict__以字典形式获取对象的属性和值
#获取对象中封装的所有的属性
class Foo:
    def __init__(self,name,pwd,eamil):
        self.name = name
        self.pwd =  pwd
        self.eamil = eamil
obj = Foo('guohan','123','888')
print(obj.__dict__)
#>>>{'name': 'guohan', 'pwd': '123', 'eamil': '888'}
setattr(obj,'name','gh')
print(obj.__dict__)
#>>>{'name': 'gh', 'pwd': '123', 'eamil': '888'}

#获取对象中封装的所有的属性(私有属性也可以看,因为私有属性本质上还是实例对象的属性    只是普通的对象.属性无法直接看到    而__dict__可以获取你所有属性不管你私有还是公有)
class Foo:
    def __init__(self,name,pwd):
        self.name = name  #设置私有属性,对象不能直接访问
        self.__pwd = pwd
    @property
    def func(self):
        return self.__pwd  
    @func.setter
    def func(self,value):
        self.__pwd = value
    @func.deleter
    def func(self):
        del self.__pwd
obj = Foo('guohan','123')
obj.func = 888
print(obj.__dict__)
>>>{'name': 'guohan', '_Foo__pwd': 888}

    4.继承:    搞清楚self是谁由谁创建 调用方法时去self自己的类中去找  

            查找方法顺序:先再自己类中找再去基类找(多个基类则由左至右)  时刻注意self是谁

    5.多态:    对于一个函数而言,Python对于参数的类型不会限制,那么传入参数时就可以是各种类型,在函数中如果有例如:arg.方法,那么就是对于传入类型的一个限制(类型必须有该方法)。
              这就是鸭子模型只要有该方法,就是我们要想的类型

 

    6.私有属性和私有方法:

            私有属性self__属性名 = 值  私有属性不允许类的对象直接访问,只能通过类内部的公有方法间接操作  比如类中公有方法可以访问私有属性故用property修饰方法将其伪装成属性再去间接访问私有属性

# 强制访问私有成员

class Foo:
    def __init__(self,name):
        self.__x = name


obj = Foo('alex')

print(obj._Foo__x) # 强制访问私有实例变量

 

 

 

            私有方法def__方法名():  私有方法不能被类的对象直接调用,只能在类内部使用。

 

 

应用

分页查看(面向对象版)
#分页显示(面向对象版)

#显示页面内容等方法:面向对象编程
#用户输入:函数式编程


class Page:
    page_count = 10
    def __init__(self,path,page):
        self.path = path
        self.page = int(page)
    def content(self):
        page_content = []
        data = 0
        stat = Page.page_count*(self.page-1)
        end = Page.page_count*self.page
        with open(self.path,'r',encoding='utf-8') as obj:
            for item in obj:
                new_item = item.strip('\n')
                if data>=end:
                    break
                elif data>=stat:
                    page_content.append(new_item)
                data+=1
        for item in page_content:
            print(item)
while True:
    page = input('输入查看的页码(N退出):')
    path = input('输入查看的文件名:')
    if page.upper() == 'N':
        break
    obj = Page(path,page)
    obj.content()

 

 

    7.栈:后进先出

class Foo(object):
    """
    后进先出(理解:地铁站,后进车厢的离门近,先出去)
    """
    def __init__(self):
        self.data_list = []

    def push(self, val):
        """
        向栈中压入一个数据(入栈)
        :param val:
        :return:
        """
        self.data_list.append(val)

    def pop(self):
        """
        从栈中拿走一个数据(出栈)
        :return:
        """
        return self.data_list.pop()
    
obj = Foo()
obj.push(6)
obj.push(7)
obj.push(8)
print(obj.pop())
#>>>8

 

posted @ 2025-10-14 13:33  guohan  阅读(17)  评论(0)    收藏  举报