首页 > 其他 > 详细

面向对象

时间:2019-11-07 01:06:44      阅读:81      评论:0      收藏:0      [点我收藏+]
# class 定义
class My_class(object):
    # 类属性,所有实例共有,优先级低于实例属性,只能通过My_class.count修改,修改后该类的其它实力和子类都会同步变化。
    # stu.count=1只是再stu下新建一个高优先级的count=1的属性,对My_class.count无影响。
    # del stu.count 后My_class.count==stu.count
    # 实例属性属于各个实例所有,互不干扰;
    # 类属性属于类所有,所有实例共享一个属性;
    # 不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。
    count = -1

    # 特殊的__slots__变量,来限制该class实例能添加的属性,
    # 注意私有属性的写法,class方法不必写出,但通过类实例加入方法要写入,
    # 且slots会对类属性设为只读,并且slots对继承的子类是不起作用的.
    # __slots__ = ('__name', '__age','__score','args','kw','gender','set_gender','param')

    # 初始化方法
    def __init__(self, name, score, age=21, *args, **kwargs):
        # 实例属性
        self.__name = name
        self.__score = score
        self.__age = age
        self.args = args
        self.kw = kwargs

        self.index = 0

    # get/set访问私有变量。
    def set(self, name, score, age):
        self.__name = name
        self.__score = score
        self.__age = age

    def get(self):
        return [self.__name, self.__score, self.__age]

    def print_score(self):
        print('name:%s,score:%s,age:%s,args:%s,kwargs:%s' % (self.__name, self.__score, self.__age, self.args, self.kw))

    # 简化get/set ,可通过stu.name实现访问/修改__name功能。
    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    # 只定义get,__age就变为只读属性。
    @property
    def age(self):
        return self.__age

    # 实现len(stu)
    def __len__(self):
        return len(self.args)

    # toString
    def __str__(self):
        return 'name:%s,score:%s,age:%s,args:%s,kwargs:%s' % (self.__name, self.__score, self.__age, self.args, self.kw)

    __repr__ = __str__

    # 实现遍历就必须实现一个__iter__()方法,该方法返回一个迭代对象,
    # 然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,
    # 直到遇到StopIteration错误时退出循环。
    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.args[0]):
            raise StopIteration
        else:
            self.index = self.index + 1
            return self.args[0][self.index - 1]

    # 下标访问
    def __getitem__(self, index):
        if isinstance(index, slice):
            start = index.start
            stop = index.stop
            step = index.step
            return self.args[0][start:step:stop]
        else:
            return self.args[0][index]

    # 当调用不存在的属性时,Python解释器会试图调用__getattr__(self, name)来尝试获得属性,
    # 只有在没有找到属性的情况下,才调用__getattr__,已有的属性,不会在__getattr__中查找。
    def __getattr__(self, name):
        if name == 'weight':
            return 68

    # 可以实现针对完全动态的情况作调用,如网站地址。
    # class Chain(object):
    #
    #     def __init__(self, path=''):
    #         self._path = path
    #
    #     def __getattr__(self, path):
    #         return Chain('%s/%s' % (self._path, path))
    #   >>Chain().status.user.timeline.list
    #       '/status/user/timeline/list'

    # 实现直接对实例进行调用stu(args)
    def __call__(self, *args, **kwargs):
        print('i\'m callable,%s,%s' % (args, kwargs))

    def saySomething(self):
        print('i\'m super class')


# 创建实例
stu = My_class('huang', 88, 33, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], key_0='vale_0', key_1='vale_1')
stu.print_score()

# 对实例变量绑定任何数据
stu.gender = 'male'
print(stu.gender)


# 对实例绑定方法,只对该实例起作用
def set_gender(self, gender):
    self.gender = gender


from types import MethodType

stu.set_gender = MethodType(set_gender, stu)
stu.set_gender('female')
print(stu.gender)

# 对类绑定方法,对该类所有实例起作用
My_class.set_gender = set_gender
foo = My_class('huang', 88, 33, [1, 2, 3], key_0='vale_0', key_1='vale_1')
foo.set_gender('female')
print(foo.gender)

# 访问修改私有属性
print(stu.get())
stu.set('hu', 98, 20)
print(stu.get())


# stu.__name 无法访问,但可通过 _classname__propertyname 强制访问私有变量,不建议这么做。
# stu._My_class__name='qiang'
# print(stu._My_class__name)

# 子类
class Subclass(My_class):

    # 复写父类方法
    def saySomething(self):

        # 子类调用父类方法
        # super().saySomething

        print('i\'m subclass')


sub_stu = Subclass('huang', 88, 33, [1, 2, 3], key_0='vale_0', key_1='vale_1')
sub_stu.print_score()
stu.saySomething()
sub_stu.saySomething()

# 实例与继承类关系
print(isinstance(stu, My_class),
      isinstance(sub_stu, My_class),
      isinstance(stu, Subclass)
      )


# 有saysomething功能的任何类
class Other_class(object):
    def saySomething(self):
        print('i\'m other class')


others = Other_class()


# 继承与多态,不管实现只管调用。
def say_twice(stu):
    stu.saySomething()


say_twice(stu)
say_twice(sub_stu)
# 鸭子类型,不管他是否是鸭子,他的行为像鸭子就行。
say_twice(others)

import types

# 实例类型判断
print(type(123) == type(456),
      type(123) == int,
      type('abc') == type('123'),
      type('abc') == str,
      type('abc') == type(123))

print(
    type(say_twice) == types.FunctionType,
    type(abs) == types.BuiltinFunctionType,
    type(lambda x: x) == types.LambdaType,
    type((x for x in range(10))) == types.GeneratorType,
)

print(
    isinstance('a', str),
    isinstance(123, int),
    isinstance(b'a', bytes)
)

# 判断[1,2,3]是否是list或者 tuple
print(isinstance([1, 2, 3], (list, tuple)))

# 获得stu所有的属性与方法
print(dir(stu))

# 造作对象属性,只有在不知道对象信息的时候,我们才会去获取对象信息,优先使用object.property操作属性。
print(hasattr(stu, 'kw'), hasattr(stu, 'get'))

# none为可选参数,如果没有 kw属性才返回None
print(getattr(stu, 'kw', None))

# 获得函数,print_stu()==print_score()
print_stu = getattr(stu, 'print_score')
print_stu()

# 设置属性,等价于stu.param=20
setattr(stu, 'param', 20)
print(stu.param)

other_stu = My_class('huang', 88, 33, [1, 2, 3], key_0='vale_0', key_1='vale_1')

print(My_class.count, stu.count, sub_stu.count, other_stu.count)

stu.count = 1
# 只有stu.count 变化
print(My_class.count, stu.count, sub_stu.count, other_stu.count)

My_class.count = 2
# My_class 其它实例和子类都同步变化
print(My_class.count, stu.count, sub_stu.count, other_stu.count)

del stu.count
# stu.count值变回my_class.count值
print(My_class.count, stu.count, sub_stu.count, other_stu.count)

# 简化get/set实现读写
print(stu.name)
stu.name = 'huangqiang'
print(stu.get())

# 简化get实现只读
print(stu.age)


# stu.age=99999
# print(stu.get())

# 多重继承
class Anaimal(object):
    def eat(self):
        print('i can eat')


class Flyable(object):
    def fly(self):
        print('i can fly')


class Runable(object):
    def run(self):
        print('i can run')


class Dog(Anaimal, Runable):
    pass


dog = Dog()
dog.eat()
dog.run()

# 定制类
# 获得长度
print(len(stu))

# toString
print(stu)

# 遍历对象
for i in stu:
    print(i)

# 下标访问
print(stu[3])
print(stu[1:3:9])

# 动态属性
print(stu.weight)

# 直接调用对象
stu([1, 2, 3, 4], key='value')
print(callable(stu), callable(dog))

from enum import Enum

# Month类型的枚举类,可以直接使用Month.Jan来引用一个常量,或者枚举它的所有成员
# value属性则是自动赋给成员的int常量,默认从1开始计数.
Month = Enum('Mon', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

print(Month(1), Month.Jan, Month.Jan.value)

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

from enum import Enum, unique


# unique保证value唯一
@unique
class Weekday(Enum):
    Sun = 0  # Sun的value被设定为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6


print(Weekday(0), Weekday.Sun, Weekday.Sun.name, Weekday.Sun.value)
for name, member in Weekday.__members__.items():
    print(name, '=>', member, ',', member.value)

面向对象

原文:https://www.cnblogs.com/huangqiang97/p/11809641.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!