面向对象(绑定方法-非绑定方法-隐藏属性-property装饰器-面向对象的三大特征)

一、对象的绑定方法

class Student:
    school = 'SH'

    def __init__(self, name, age, gender):
        # self:对象自己
        self.name = name
        self.age = age
        self.gender = gender

    '''
    绑定给对象的方法,有什么特殊之处?
        1.函数的第一个形参self就是对象自己
        2.绑定给对象的方法就由对象来调用,它会把对象自己当成第一个参数传给方法的第一个形参self
    '''
    def tell_info(self):
        # self:对象自己
        print('name:%s, age:%s, gender:%s' % (self.name, self.age, self.gender))


stu = Student('kevin', 18, 'male')
'''绑定给对象的方法目的不是想让类来调用的,但是,类也能调用,只不过方法里面有几个参数就要传几个参数'''
stu.tell_info()

二、绑定给类方法

配置文件(settings.py)

IP = '127.0.0.1'
PORT = 3306

import settings
''' ip + port 可以唯一确定一台计算机上的软件 '''
class Mysql():
    def __init__(self, ip, port):
        self.ip = ip
        self.port = port

    '''
    注意:
        加上@classmethod后,该方法已经变成绑定给类的方法,而不是绑定给对象了
        所以,绑定给类后,就用类来调用,而不是用对象来调用了
    '''
    @classmethod
    # def from_func(self):  # self:就是类名
    def from_func(cls):  # cls:就是类名
        # return Mysql('127.0.0.1', 3306)
        print('from func')
        # return Mysql(settings.IP, settings.PORT)
        # return self(settings.IP, settings.PORT)
        return cls(settings.IP, settings.PORT)

obj = Mysql('127.0.0.1', 3306)
# print(obj.ip)  # 127.0.0.1
# print(obj.port)  # 3306

# res = obj.from_func()
# print(res.ip)
# print(res.port)

'''
    绑定给类的方法就由类来调用,特殊之处就是:会把类名当成一个参数传给方法的第一个形参
'''
res = Mysql.from_func()
print(res)  # <__main__.Mysql object at 0x000001E1A947AE80>
print(res.ip)  # 127.0.0.1
print(res.port)  # 3306

三、非绑定方法

'''
言外之意就是不绑定给类使用,也不绑定给对象使用
静态方法:static
补充:uuid
import uuid

"""只要随机串的长度一定,理论上,只要次数足够多,就一定会出现重复的可能"""

print(uuid.uuid4())  # 65f1ff6b-dd39-441a-8788-0dfde07d6922

'''
import random
import uuid

# print(uuid.uuid4())
# 例如:订单号中一定不能重复,如何保证订单号的不重复
# res = uuid.uuid4() + 时间戳


class Student:
    school = 'SH'

    def __init__(self, name, age, gender):
        # self:对象自己
        self.name = name
        self.age = age
        self.gender = gender
        self.id = self.create_id()

    '''
    注意:
        加上@staticmethod后,该方法谁都不能绑定,谁都能来调用,此时就是普通方法
        
        那什么时候使用静态方法呢?
            一般就是方法里面既不用对象,也不用类的时候就使用静态方法
            例如,生成验证码get_code()
    '''
    @staticmethod
    def create_id():
        return uuid.uuid4()

    @staticmethod
    def get_code(n):
        code = ''
        for i in range(n):
            random_int = str(random.randint(0, 9))
            random_upper = chr(random.randint(65, 90))
            random_lower = chr(random.randint(97, 122))

            code += random.choice([random_upper, random_lower, random_int])
        return code

    '''若方法里面既用到了对象,又用到了类,那么方法给谁绑定最合适?'''
    def func(self):
        print(self)
        print(self.__class__)  # <class '__main__.Student'>
        print(self.__class__.__name__)  # Student


stu = Student('张三', 19, 'female')
# print(stu.id)  # 每实例化一次就生成一次唯一的id


# res = stu.create_id()
# print(res)

# print(Student.create_id())


print(stu.func())


四、隐藏属性

1. 如何隐藏?
2. 为什么隐藏?
"""
    1. 隐藏属性在类的定义阶段,发生了变形,_类名__属性名
    2. 不但可以隐藏类属性、方法、对象的属性都可以隐藏
    3. 隐藏属性对外不对内,对类的外部是隐藏的,而对类的内部是开放的
"""
# 1. 如何隐藏
class Student():
    # '_Student__school': 'SH' _类名__属性名: 'SH'
    # school = 'SH'  # 把school属性已经隐藏了,隐藏的意思是,在类外部不能使用了
    __country = 'China'
    def __init__(self, name, age, gender):
        self.__name = name  # _Student__name
        self.age = age
        self.gender = gender

    def __func(self):  # _Student__func  _类名__函数名
        print('from func')

    # def index(self):
    #     return self.__school  # self._Student__school

    def get_country(self):
        return self.__country


    def set_country(self, v):
        if type(v) is not str:
            return
        Student.__country = v

stu = Student('kevin', 19, 'male')
print(stu.__school)

查看类的名称空间
print(Student.__dict__)
print(stu.__school)
变形之后的数据目的不是想让我们在外部使用的, 但是在类的外部也能使用
print(stu._Student__school)  # SH

stu._Student__func()

print(stu.name)
print(stu._Student__name)

res=stu.index()
print(res)  # SH

############2. 为什么要隐藏?
"""由于隐藏属性是对外不对内的,所以,我们要想在类的外部使用,就需要在类的内部开放一个接口,返回隐藏属性的值,以便更好的对外做限制"""
print(stu.school)

Student.school = 'beijing'
Student.school = 123
print(stu.school)

Student.country = 123

stu.set_country('唐')
stu.set_country(123)
print(stu.get_country())

五、装饰器(@property)

方式1"""
    1.隐藏属性在类的定义阶段,发生了变形,_类名__属性名
    2.不但可以隐藏类的属性,方法、对象的属性都可以隐藏
    3.隐藏属性对外部对内,对类的外部是隐藏的,而对类的内部是开放的
"""
class Student:
    '''
        隐藏school属性,隐藏的意思是:在类外部不能使用
        注意:
            在外部变形之后的数据 目的不是想让我们在外部使用的,
            例如:print(stu._Student__school)在类的外部也能使用
        _类名__属性名: 'SH'
    '''
    __school = 'SH'
    __country = "China"
    __city = 'shanghai'

    def __init__(self, name, age, gender):
        # self:对象自己
        self.__name = name
        self.age = age
        self.gender = gender

    def __func(self):  # _Student__func _类名__方法名
        print('from func')

    # def index(self):
    #     return self.__school

    @property
    def country(self):
    # def get_country(self):
        return self.__country

    @country.setter
    def country(self, v):
    # def set_country(self, v):
        if type(v) is not str:
            return
        Student.__country = v

    @country.deleter
    def country(self):
        print('可以删除了')
        del Student.__country

    @property
    def city(self):
        return self.__city

    @city.setter
    def city(self, v):
        Student.__city = v

    @city.deleter
    def city(self):
        del Student.__city


stu = Student('张三', 19, 'male')
# print(stu.__school)  # 报错

print(Student.__dict__)
# print(stu._Student__school)  # SH

# print(stu.__func)  # 报错

print(stu.__dict__)

# res = stu.index()
# print(res)  # SH


# stu.set_country("USA")
# print(stu.get_country())  # USA

print(stu.country)  # China

stu.country = 'USA'
print(stu.country)  # USA


del stu.country


方式2class Student:
    __country = "China"

    def __init__(self, name, age, gender):
        # self:对象自己
        self.__name = name
        self.age = age
        self.gender = gender

    def get_country(self):
        return self.__country

    def set_country(self, v):
        Student.__country = v

    def del_country(self):
        del Student.__country

    '''这种方式是有顺序要求的'''
    country = property(get_country, set_country, del_country)


stu = Student('张三', 19, 'male')
print(stu.country)  # China

stu.country = "大唐"
print(stu.country)  # 大唐

del stu.country

小练习(BMI指数)

class Bmi():
    def __init__(self, weight, height):
        self.weight = weight
        self.height = height

    @property
    def bmi(self):
        return self.weight / (self.height ** 2)


bmi = Bmi(75, 1.72)
print(bmi.bmi)


六、对象的三大特征

1.封装:也是一种思想,把冗余的代码,重复的代码都封装成函数,以后每次都调用函数来用
2.继承:
	1. 什么是继承?
    	"""继承就是新建类的一种方式,新建出来的类称为是子类或者叫派生类,被继承的类称为是父类或者叫基类"""
        # 子类可以继承父类的所有属性和方法!
    
    2. 为什么要继承?
    	类解决什么问题:解决的是对象与对象之间的代码冗余问题
        继承解决什么问题:解决的是类与类之间的代码冗余问题
        
    3. 怎么样继承?
    	新式类:继承了object类的子子孙孙类都是新式类
        经典类:没有继承object类的子子孙孙类都是经典类
        
        """只有在python2中才区分经典类和新式类,因为在python3中都是新式类"""
        
	# class Parent1(object):
	#     pass
	#
	# class Parent2:
	#     pass
	#
	# # 直接把类名写在括号里就是继承,括号里面写的类是父类,括号外的是子类
	# class Sub1(Parent1):
	#     pass
	#
	#
	# # python中支持多继承, 括号里面可以写多个类
	# class Sub2(Parent1, Parent2):
	#     pass
	#
	# # 如何查看一个类继承了哪些父类?
	# print(Sub1.__bases__)
	# print(Sub2.__bases__)
	# print(Parent1.__bases__)  # object
	
	
	
	# 以学生选课系统为例
	
	class People():
	    school = 'SH' # 严格依赖继承
	
	    def __init__(self, name, age, gender):
	        self.name = name
	        self.age = age
	        self.gender = gender
	
	
	class Student(People):
	    def __init__(self, name, age, gender, course):
	        """这个是指名道姓的调用方法,不依赖于继承"""
	        People.__init__(self, name, age, gender) # 有什么特殊之处,
	        self.course = course
	
	    def choose_course(self):
	        pass
	
	stu = Student('kevin', '19', 'male', 'python')
	
	# 对象属性的查找顺序:先从对象自己的名称空间查找,如果找不到,再去类中取查找,如果找不到,去继承的父类转中查找,
	print(stu.school)
	print(stu.name)
	class Teacher(People):
	    def __init__(self,name, age, gender, level):
	        People.__init__(self, name, age, gender)  # 有什么特殊之处,
	        self.level = level
	
	    def score(self):
	        pass
	
	
	tea = Teacher("ly", 20, 'female', 10)
	print(tea.school)
	
3.多态
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值