类的封装,property装饰器的作用,绑定方法与非绑定方法,反射,

类的封装

'''
1、什么封装
    封:属性对外是隐藏的,但对内是开放的
    装:申请一个名称空间,往里装入一系列名字/属性

2、为什么要封装
    封装数据属性的目的
        首先定义属性的目的就是为了给类外部的使用者使用的,
        隐藏之后是为了不让外部使用直接使用,需要类内部开辟一个接口
        然后让类外部的使用通过接口来间接地操作隐藏的属性。
        精髓在于:我们可以在接口之上附加任意逻辑,从而严格控制使用者对属性的操作

    封装函数属性
        首先定义属性的目的就是为了给类外部的使用者使用的,
        隐藏函数属性是为了不让外部直接使用,需要类内部开辟一个接口
        然后在接口内去调用隐藏的功能
        精髓在于:隔离了复杂度



3、如何封装

'''
# 如何隐藏:在属性前加上__开头


#1、 这种隐藏仅仅只是一种语法上的变形操作
#2、 这种语法上的变形只在类定义阶段发生一次,因为类体代码仅仅只在类定义阶段检测一次
#3、 这种隐藏是对外不对内的,即在类的内部可以直接访问,而在类的外则无法直接访问,原因是
#    在类定义阶段,类体内代码统一发生了一次变形

#4、 如果不想让子类的方法覆盖父类的,可以将该方法名前加一个__开头


# class People:
#     __country='China' #_People__country='China'
#     __n=100 #_People__n=100
#     def __init__(self,name,age,sex):
#         self.__name=name #self._People__name=name
#         self.age=age
#         self.sex=sex
#
#     def eat(self):
#         print('eat.....')
#         print(People.__country) #People._People__country
#         print(self.__name) #self._People__name

# People.eat(123)
# print(People.__country)

# peo1=People('egon',18,'male')
# peo1.eat()
# print(peo1.__name)

# print(People.__dict__)
# print(People.__country)
# print(People._People__country)

# People.__x=11
# print(People.__dict__)


# peo1=People('egon',18,'male')
# print(peo1.__dict__)
# peo1.__x=111
# print(peo1.__dict__)

# class Foo:
#     def __f1(self): #_Foo__f1
#         print('Foo.f1')
#
#     def f2(self):
#         print('Foo.f2')
#         self.__f1() #self._Foo__f1
#
# class Bar(Foo):
#     def __f1(self): #_Bar__f1
#         print('Bar.f1')
#
# obj=Bar()
# obj.f2()




class People:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age

    def tell_info(self):
        print('%s:%s' %(self.__name,self.__age))

    def set_info(self,name,age):
        if type(name) is not str:
            # print('用户名必须为str类型')
            # return
            raise TypeError('用户名必须为str类型')

        if type(age) is not int:
            # print('年龄必须为int类型')
            # return
            raise TypeError('年龄必须为int类型')
        self.__name=name
        self.__age=age

peo1=People('egon',18)
# peo1.name=123
# peo1.age
# peo1.tell_info()

peo1.set_info('egon',19)
# peo1.tell_info()
封装,为什么封装

property装饰器的作用

# property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接引用
# class People:
#     def __init__(self,name,weight,height):
#         self.name=name
#         self.weight=weight
#         self.height=height
#
#     @property
#     def bmi(self):
#         return self.weight / (self.height ** 2)
#
# peo1=People('egon',75,1.8)
#
# peo1.height=1.85
# print(peo1.bmi)


'''
class People:
    def __init__(self,name):
        self.__name=name

    @property # 查看obj.name
    def name(self):
        return '<名字是:%s>' %self.__name

    @name.setter #修改obj.name=值
    def name(self,name):
        if type(name) is not str:
            raise TypeError('名字必须是str类型傻叉')
        self.__name=name

    @name.deleter #删除del obj.name
    def name(self):
        # raise PermissionError('不让删')
        print('不让删除傻叉')
        # del self.__name

peo1=People('egon')
# print(peo1.name)

# print(peo1.name)

# peo1.name='EGON'
# print(peo1.name)

del peo1.name
property

绑定方法与非绑定方法

'''
1、绑定方法
    特性:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入
         《《《精髓在于自动传值》》》

    绑定方法分为两类:
        1.1 绑定给对象方法
            在类内部定义的函数(没有被任何装饰器修饰的),默认就是绑定给对象用的
        1.2 绑定给类的方法:
            在类内部定义的函数如果被装饰器@classmethod装饰,
            那么则是绑定给类的,应该由类来调用,类来调用就自动将类当作第一个参数自动传入



2、非绑定方法
    类中定义的函数如果被装饰器@staticmethod装饰,那么该函数就变成非绑定方法
    既不与类绑定,又不与对象绑定,意味着类与对象都可以来调用
    但是无论谁来调用,都没有任何自动传值的效果,就是一个普通函数



3 应用
    如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给类的方法
    如果函数体代码需要用外部传入的对象,则应该将该函数定义成绑定给对象的方法
    如果函数体代码既不需要外部传入的类也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数


'''

# class Foo:
#     @classmethod
#     def f1(cls):
#         print(cls)
#
#     def f2(self):
#         print(self)
#
#
# obj=Foo()
# print(obj.f2)
# print(Foo.f1)

# Foo.f1()
# print(Foo)


#1、f1绑定给类的
# 了解:绑定给类的应该由类来调用,但对象其实也可以使用,只不过自动传入的仍然是类
# print(Foo.f1)
# print(obj.f1)
# Foo.f1()
# obj.f1()

#2、f2是绑定给对象的
# obj.f2()
# Foo.f2(obj)

import settings
import uuid

class Mysql:
    def __init__(self,ip,port):
        self.uid=self.create_uid()
        self.ip=ip
        self.port=port

    def tell_info(self):
        print('%s:%s' %(self.ip,self.port))

    @classmethod  
    def from_conf(cls):
        return cls(settings.IP, settings.PORT)

    @staticmethod
    def func(x,y):
        print('不与任何人绑定')

    @staticmethod
    def create_uid():
        return uuid.uuid1()

# 默认的实例化方式:类名(..)
obj=Mysql('10.10.0.9',3307)

# 一种新的实例化方式:从配置文件中读取配置完成实例化
# obj1=Mysql.from_conf()
# obj1.tell_info()

# obj.func(1,2)
# Mysql.func(3,4)
# print(obj.func)
# print(Mysql.func)

print(obj.uid)
绑定与非绑定

反射

什么是反射
    通过字符串来操作类或者对象的属性

  

# d = {'name': '123'}
# print(isinstance(d,dict))  # 是不是同一类型
# class Foo:
#     pass
# class Bar(Foo):
#     pass
#
# print(issubclass(Bar,Foo))   # Bar 是不是Foo的子类
#
#
# class People:
#     def __init__(self, name, ip, port):
#         self.name = name
#         self.ip = ip
#         self.port = port
#
#
#     def get(self):
#         print('GET function')
#
#     def see(self):
#         print('SEE function')
#
#     def run(self):
#         while True:
#             chioce = input(">>>>>>").strip()
#             if hasattr(self, chioce):
#                 monthod = getattr(self, chioce)
#                 monthod()
#             else:
#                 print("没有这个命令")

#             monthod = getattr(self,chioce, None)
#             if monthod is None:
#                 print('没有这个命令')
#             else:
#                 monthod()
#
# #
#
#
# peo1 =People('egon', '12','222.10')
# hasattr(peo1,'see')  # 有没有这个属性  有就返回True
# getattr(peo1,'see',None)  # 给我这个属性, 没有就返回None
# setattr(peo1,'name','alex')  # 改掉这个特征
# delattr(peo1,'name')   # 删除这个属性 , 只能删除特征,不能删除函数
# print(hasattr(peo1,'run'))


# class People:
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#
#     def __str__(self):  # 自动触发,在打印时
#         return '%s\t%s' % (self.name, self.age)
#
#
# peop1 = People('egon', '18')
# peop2 = People('alex', '81')
# print(peop1)
# print(peop2)


# class People:
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#         self.f = open(r'a.txt', 'rt', encoding='utf-8')
#
#     def __del__(self):
#         # del 在回收python文件时自动触发,把不属于python的资源也一起关闭,相当于临终遗言
#         print('>>>>>>')
#         self.f.close()
#
#
# obj = People('egon', 18)
#
# print(123)
反射的几种使用方法和内置的python方法

 

posted @ 2018-07-02 15:00  谢金涛  阅读(133)  评论(0编辑  收藏  举报