day18(@反射,类的内置方法)

1.复习

class 类名(父类1,父类2):
    静态属性 = ''           静态属性 类属性
    def __init__(self):     初始化方法
        self.name = 'alex'

    def func(self):         动态属性 方法
        print(self.age)
对象 = 类名()
对象.方法名()
对象.属性名
对象.name
对象.age = 18
对象.func()    类名.func(对象)
组合 :表达的是 什么有什么的关系       *****
    一个类的属性 是另外一个类的对象
class Teacher:
    pass
class Course:
    def __init__(self,name,price,period):
        self.name = name
        self.price = price
        self.period = period
python = Course('python',19800,'6 months')
class Classes:
    def __init__(self,name,course):
        self.name = name
        self.course = course
        # self.course_name = 'python'
pys9 = Classes('python_s9',python)
print(pys9.course.name)
python.name = 'python全栈'
print(pys9.course.name)

命名空间 : 类和对象分别存在不同的命名空间中

面向对象的三大特性 : 继承 多态 封装
继承 :
    单继承 :  ****
        父类(超类、基类)
        子类(派生类):派生方法和派生属性
        子类的对象在调用方法和属性 : 先用自己的 自己没有 才用父类的
    多继承 :(面试)
        不会超过三个父类,不要超过三层  ***
        如果子类自己有用自己的,如果没有就用离子类最近的那个父类的方法
        抽象类和接口类   **
        经典类和新式类 继承规则不同 深度优先和广度优先  ***** (面试)
    super 只能在python3中使用   mro   ****
        super是根据mro广度优先顺序找上一个类
多态 : (面试)
    多态和鸭子类型
封装 :   *** (面试)
    私有的
    __名字
    只能在类的内部调用 子类都无法继承
三个装饰器
    @property         ****   规范 面试   #@name.setter
    @staticmethod     ***
    @classmethod      *****  当一个方法只使用了类的静态变量时 就给这个方法加上@classmethod装饰器,默认传cls参数

class Goods:
    __discount = 0.8
    @classmethod
    def change_discount(cls):
        cls.__discount = 0.5
Goods.change_discount()

2.反射

class A:pass
class B(A):pass
a = A()
print(isinstance(a,A))
print(issubclass(B,A))
print(issubclass(A,B))

反射 : 是用字符串类型的名字 去操作 变量
name = 1
eval('print(name)')  # 安全隐患

反射 就没有安全问题

反射对象中的属性和方法   # hasattr getattr setattr delattr
class A:
    def func(self):
        print('in func')
a = A()
a.name = 'alex'
a.age = 63
# 反射对象的属性
ret = getattr(a,'name')  # 通过变量名的字符串形式取到的值
print(ret)
print(a.__dict__)
变量名 = input('>>>')   # func
print(getattr(a,变量名))
print(a.__dict__[变量名])

# 反射对象的方法
a.func()
ret = getattr(a,'func')
ret()

class A:
    price = 20
    @classmethod
    def func(cls):
        print('in func')
# 反射类的属性
# A.price
print(getattr(A,'price'))

# 反射类的方法 :classmethod staticmethod
# A.func()
if hasattr(A,'func'):
    getattr(A,'func')()

模块
import my
反射模块的属性
print(my.day)
print(getattr(my,'day'))

反射模块的方法
getattr(my,'wahaha')()

内置模块也能用
time
asctime
import time
print(getattr(time,'time')())
print(getattr(time,'asctime')())

def qqxing():
    print('qqxing')
year = 2018
import sys
print(sys.modules['__main__'].year)
反射自己模块中的变量
print(getattr(sys.modules['__main__'],'year'))

反射自己模块中的函数
getattr(sys.modules['__main__'],'qqxing')()
变量名 = input('>>>')
print(getattr(sys.modules[__name__],变量名))

要反射的函数有参数怎么办?
print(time.strftime('%Y-%m-%d %H:%M:S'))
print(getattr(time,'strftime')('%Y-%m-%d %H:%M:S'))

一个模块中的类能不能反射得到
import my
print(getattr(my,'C')())
if hasattr(my,'name'):
    getattr(my,'name')

重要程度半颗星
setattr  设置修改变量
class A:
    pass
a = A()
setattr(a,'name','nezha')
setattr(A,'name','alex')
print(A.name)
print(a.name)

# delattr 删除一个变量
delattr(a,'name')
print(a.name)
delattr(A,'name')
print(a.name)

3.类的内置方法

内置的类方法 和 内置的函数之间有着千丝万缕的联系
双下方法
obj.__str__  str(obj)
obj.__repr__ repr(obj)
class Teacher:
    def __init__(self,name,salary):
        self.name = name
        self.salary = salary
    def __str__(self):
        return "Teacher's object :%s"%self.name
    def __repr__(self):
        return str(self.__dict__)
    def func(self):
        return 'wahaha'
nezha = Teacher('哪吒',250)
print(nezha)  # 打印一个对象的时候,就是调用a.__str__
print(repr(nezha))
print('>>> %r'%nezha)
a.__str__ --> object
object  里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址
l = [1,2,3,4,5]   # 实例化 实例化了一个列表类的对象
print(l)
%s str()  直接打印 实际上都是走的__str__
%r repr()  实际上都是走的__repr__
repr 是str的备胎,但str不能做repr的备胎

print(obj)/'%s'%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串
如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__。
repr(),只会找__repr__,如果没有找父类的

内置的方法有很多
不一定全都在object中
class Classes:
    def __init__(self,name):
        self.name = name
        self.student = []
    def __len__(self):
        return len(self.student)
    def __str__(self):
        return 'classes'
py_s9= Classes('python全栈9期')
py_s9.student.append('二哥')
py_s9.student.append('泰哥')
print(len(py_s9))
print(py_s9)

__del__
class A:
    def __del__(self):    析构函数: 在删除一个对象之前进行一些收尾工作
        self.f.close()
a = A()
a.f = open()    打开文件 第一 在操作系统中打开了一个文件 拿到了文件操作符存在了内存中
del a           a.f 拿到了文件操作符消失在了内存中
del a    del 既执行了这个方法,又删除了变量
引用计数


__call__
class A:
    def __init__(self,name):
        self.name = name
    def __call__(self):
        '''
        打印这个对象中的所有属性
        :return:
        '''
        for k in self.__dict__:
            print(k,self.__dict__[k])
a = A('alex')()

猜你喜欢

转载自blog.csdn.net/qq_36227329/article/details/81266554