初学Python的学习笔记9----面向对象编程(获取对象信息、实例属性和类属性)、面向对象高级编程(使用__slots__、使用@property)...

本文介绍了Python中如何获取对象信息,包括类型判断、属性和方法的获取与操作,并深入探讨了实例属性与类属性的区别。此外,还讲解了Python面向对象高级编程中的多重继承、定制类和元类等内容。

1.获取对象信息

(1)使用type():判断对象类型,返回对应的class类型

 print type(123)  # int
 print type('yj')  # 字符串
 print type(True)  # 布尔值
 print type(None)
 print type(abs)  # 函数
#输出信息
<type 'int'>
 <type 'str'>
 <type 'bool'>
 <type 'NoneType'>
 <type 'builtin_function_or_method'>
 # 具体这种的没弄清楚啥意思
# 判断一个对象是否是函数,使用types模块中定义的变量
import types
 def fn():
     pass
 print type(fn) == types.FunctionType    # True

(2)使用isinstance():class的继承关系,一种对象是否是某种类型

class Animal(object):
    def run(self):
        print('Animal is running......')

class Dog(Animal):
    def run(self):
        print('Dog is running......')

class Happy(Dog):
    def run(self):
        print('Happy is running......')

animal = Animal()
dog = Dog()
happy = Happy()

print isinstance(happy, Happy)     # True
print isinstance(happy, Dog)       # True 由于继承
print isinstance(happy, Animal)    # True 由于继承
print isinstance(dog, Dog)         # True
print isinstance(dog, Animal)      # True 由于继承

能用type()判断的基本类型也可以用isinstance()判断

isinstance(123, int)    # True
isinstance('yj', str)   # True

判断一个变量是否是某些类型中的一种

print isinstance([1,2,3], (list, tuple))    # True

(3)使用dir():获得一个对象的所有属性和方法,返回一个包含字符串的list

print dir('ABC')

在Python中,调用len()获取一个对象的长度,实际上,在len()函数内部,他自动调用该对象的__len__()

print len('ABC')
print 'ABC'.__len__()

这两个结果是等价的

(4)自己写类,使用len(),就自己写一个__len__()

class MyName(object):
    def __len__(self):
        return 50

myName = MyName()
print len(myName)     # 50

这样仅仅是把属性和方法列出来 配合getattr()/setattr()/hasattr(),可以直接操作一个对象的状态

class MyName(object):
    def __init__(self):
        self.x = 9
    def double(self):
        return self.x * self.x

myName = MyName()

测试该对象的属性:

print hasattr(myName,'x')     # True
print hasattr(myName,'y')     # False

print setattr(myName,'y',10)
print hasattr(myName,'y')     # True
print getattr(myName,'y')
print myName.y

获取属性的时候可以传入一个default,如果属性不存在,就返回默认值

print getattr(myName,'z',404)     # 404

获取对象的方法

print hasattr(myName,'double')
print getattr(myName,'double')

2.实例属性和类属性

Python是动态语言,根据类创建的实例可以任意绑定属性

(1)给实例绑定属性:通过实例变量,或者通过self变量

class Student(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

yj = Student('YJ',24)
print yj.name
print yj.age

(2) class类本身绑定属性:直接在class中定义属性,称为类属性,归class类所有

类属性,类的所有实例都可以访问到

class Student(object):
    name = 'LP'

student = Student()
print student.name      # 实例没有name属性,所以打印类属性
print Student.name      # 类属性

student.name = 'YJ'     # 实例绑定name属性
print student.name      # 实例属性优先级高于类属性,打印实例属性
print Student.name

del student.name
print student.name      # 打印类属性

PS: Python中,不要把实例属性和类属性使用相同的名字, 因为实例属性的优先级较高,相同名称的实例属性和类属性将屏蔽掉类属性, 但是删除实例属性之后,再使用相同的名称,访问到的是类属性

3.面向对象高级编程——多重继承、定制类、元类

(1)使用__slots__

1)给实例绑定方法

class Student(object):      # 声明一个类
    pass

yj = Student()      # 给实例绑定属性
yj.name = 'YJ'
print yj.name

def set_age(self,age):      # 给实例绑定方法
    self.age = age
from types import MethodType
yj.set_age = MethodType(set_age, yj)

yj.set_age(24)      # 调用方法
print yj.age

lp = Student()      # 但是,给一个实例绑定的方法,对另一个实例是不起作用的
lp.set_age()

2)给class绑定方法

class Student(object):      # 给class绑定方法,所有的实例都可以调用
    pass
def set_score(self, score):
    self.score = score
Student.set_score = set_score
yj = Student()
yj.set_score(100)
print yj.score
lp = Student()
lp.set_score(101)
print lp.score

3)使用__slots__

Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性

class Student(object):
    __slots__ = ('name','age')

lz = Student()
lz.name = 'LZ'
print lz.name
lz.age = 24
print lz.age
lz.score = 99   # 报错
PS: __slots__定义的属性仅仅是对当前实例起作用,对机场的子类不起作用
class Student(object):
    __slots__ = ('name','age')

lz = Student()
lz.name = 'LZ'
print lz.name
lz.age = 24
print lz.age

class GradeStudent(Student):
    pass
grade = GradeStudent()
print  grade.age  # 报错

PS: 子类允许定义的属性 = 自身的__slots__+父类的__slots__

(2)使用@property

  1. 普通的get/set
class Student(object):
    def get_score(self):
        return self._score
    def set_score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer')
        if value < 0 or value > 100:
            raise ValueError('score must be between 0~100')
        self._score = value


yj = Student()      # 声明实例方法
yj.set_score(99)
print yj.get_score()
yj.set_score(101)   # 报错

2)使用@property

装饰器(decorator)可以给函数添加功能。

Python内置的@property装饰器:把一个方法变成属性调用。

class Student(object):
    @property                   # 读
    def score(self):
        return self._score

    @score.setter               # 写
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer')
        if value < 0 or value > 100:
            raise ValueError('score must be between 0~100')
        self._score = value

lp = Student()
lp.score = 99   # 等价于  lp.set_score(99)
print lp.score
lp.score = 101  # 报错

3)定义只读属性:只定义getter,不定义setter

class Student(object):
    @property               # 读
    def birth(self):
        return self._birth

    @birth.setter           # 写
    def birth(self, value):
        self._birth = value

    @property               # 读
    def age(self):
        return 2015 - self._birth

lp = Student()
lp.birth = 24
print lp.birth
print lp.age

#birth可读可写;age只读。

4)一个作业

class Screen(object):
    @property               # 读
    def width(self):
        return self._width

    @width.setter           # 写
    def width(self, value):
        self._width = value

    @property               # 读
    def height(self):
        return self._height

    @height.setter          # 写
    def height(self, value):
        self._height = value

    @property               # 读
    def resolution(self):
        return self._height +  self._width
screen = Screen()
screen.width = 100
screen.height = 200
print screen.width
print screen.height
print screen.resolution

转载于:https://my.oschina.net/yj1993/blog/1573469

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值