2018-09-07类和对象2(day15)

2018-09-07  本文已影响0人  naruto711

一、内置类属性

内置类属性就是魔法属性

class Person:
    '''人类''' #类的说明文档
    # 类的字段
    number = 61
    def __init__(self,name,age,height):
        self.name = name
        self.age = age
        self.height = height
    def __trunc__(self):
        print('%s在跑步'%self.name)

    # 类方法
    @classmethod
    def show_number(cls):
        print('人类的数量为:%d亿'%cls.number)

    # 静态方法
    @staticmethod
    def destroy():
        print('人类在破坏环境!')

if __name__ == '__main__':
    p1 = Person('张三',23,179)
    # 1.__name__属性 ---类的名字(是个字符串)
    name = Person.__name__
    print(name,type(name),type(Person))
    # Person  <class 'str'>  <class 'type'>

    # 2.__class__属性 --- 获取对象对应的类(是一个类)
    # 对象的属性
    # my_class是一个类,之前类能做的事他都能做
    my_class = p1.__class__
    p2 = my_class('张三',20,200)
    print(p2.name,my_class.__name__)
    # 张三 Person

    # 3.__dict__属性 --- 将对象和类的属性及其对应的值转换成键值对存到一个字典中
    # print(Person.__dict__)
    print(p1.__dict__)
    # {'name': '张三', 'age': 23, 'height': 179}
    # 4.__doc__属性  ---获取类的说明文档
    # 类的属性
    doc = Person.__doc__
    print(doc)
    # 人类
    # 5.__module__属性 --- 获取类所在的模块对应的名字
    print(Person.__module__)
    # __main__
    # 6.__bases__属性 --- 获取当前类的父类
    # 类的属性
    print(Person.__bases__)
    #(<class 'object'>,)

二、__ slots __魔法

class Person:

    # 通过__slots__中存的元素的属性的值来约束当前这个类的对象的属性。对象的属性只能比元祖中的元素少,不能多!
    __slots__ = ('name', 'age', 'face')

    def __init__(self):
        self.name = '张三'
        self.age = 18
        self.face = 70
        # self.sex = 'boy'  # __slots__中并没有sex


if __name__ == '__main__':
    p1 = Person()
    # p1.sex = 'girl'
    # print(p1.sex)

    # p1.neme = '小明'
    print(p1.name)

    # 注意:一旦在类中给__slots__属性赋了值,那么这个类的对象的__dict__属性就不能使用了
    # print(p1.__dict__)

三、属性的私有化

python中并没有真正的私有化!
python类中默认的属性和方法都是公开的

1.私有化
2.私有化原理
class Dog:
    # 字段
    number = 100
    __count = 10

    def __init__(self):
        # 对象的属性
        self.color = '黄色'
        self.age = 3
        self.name = '大黄'
        self.__sex = '母的'

    # 对象方法
    def eat(self):
        print('%s在吃屎~'%self.name)

    # 类方法
    @classmethod
    def shout(cls):
        print(cls.__count)
        print('汪汪汪~~~')

    # 静态方法
    @staticmethod
    def function():
        print('看家!!')

dog1 = Dog()
print(Dog.number)  # 100
print(dog1.name,dog1.color,dog1.age) # 大黄 黄色 3
dog1.eat()  #10
Dog.shout() # 汪汪汪~~~
Dog.function() # 看家

# 在类的外面不能直接使用私有的属性
# print(Dog.__count)  AttributeError
# print(dog1.__sex)   AttributeError
print(dog1._Dog__sex) # 母的
print(dog1.__dict__)
# {'color': '黄色', 'age': 3, 'name': '大黄', '_Dog__sex': '母的'}

四、属性的getter和setter

1.保护类型的属性
2.添加getter
3.添加setter
class Car:
    def __init__(self):
        self.color = '黄色'
        self.type = '自行车'
        # _price属性是保护类型
        self._price = 2000

    # 给_price属性添加getter
    @property
    def price(self):
        print('在使用_price属性')
        return self._price/1000

    # 想要给一个属性添加setter,必须先给这个属性添加getter
    @price.setter
    def price(self, price):
        if isinstance(price, int) or isinstance(price, float):
            self._price = price
        else:
            self._price = 0

# 练习:声明一个员工类,其中有一个属性是是否已婚(bool),获取值之前根据存的值返回'已婚'/'未婚'
class Staff:

    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        self._is_marry = False

    @property
    def is_marry(self):
        if self._is_marry:
            return '已婚'
        return '未婚'

    @is_marry.setter
    def is_marry(self, marry):
        self._is_marry = marry


staff1 = Staff('张三', 10000)
print(staff1.is_marry)  # 未婚

staff1.is_marry = True
print(staff1.is_marry) # 已婚


if __name__ == '__main__':

    car1 = Car()
    print(car1.color) # 黄色

    # 添加完getter后就通过getter去获取属性的值
    # price就是属性_price的getter
    print(car1.price,'k')  # 实质是在调用getter对应的方法
    print(car1.price,'k') # 2.0K

    # 通过setter给_prince属性赋值。实质是在调用setter对应的方法
    car1.price = 1000
    print(car1.price) # 1.0K

    car1.price = 'abc'
    print(car1.price)  #0.0

五、继承

1.继承的语法

2.能继承哪些东西

class Person(object):
    """人类"""
    # 字段
    numer = 61

    # __slots__ = ('name', 'age')
    # 对象属性
    def __init__(self, name1='张三', age1=18):
        self.name = name1
        self.age = age1
        self.__height = 160

    # 对象方法
    def show_message(self):
        print('姓名:%s 年龄:%d' % (self.name, self.age))

    # 类方法
    @classmethod
    def show_number(cls):
        print('人类的数量:%d' % cls.numer)

    # 静态方法
    @staticmethod
    def complaint():
        print('人类殴打小动物!')


class Student(Person):
    """学生类"""
    pass


# 创建Person类的对象
p = Person()
# p.sex = 'boy'
# print(p.__dict__)

# 创建Student类的对象
stu1 = Student()

print(Student.numer) # 61
stu1.name = '李四'
print(stu1.name) # 李四
stu1.show_message() # 姓名:李四 年龄:18
Student.show_number() # 人类的数量61
Student.complaint() # 人类殴打小动物!

stu1.sex = 'girl'
print(stu1.__dict__)
# {'name': '李四', 'age': 18, '_Person__height': 160, 'sex': 'girl'}

六、方法的重写

子类继承父类,拥有父类的属性和方法,还可以添加自己的属性和方法

1.添加方法和类的字段
2.添加对象属性
3.方法的重写
4.类中方法的调用过程
class Animal:
    number = 100

    def __init__(self):
        self.age = 0
        self.sex = '雌'

    def shout(self):
        print('嗷嗷叫')

class Cat(Animal):

    def __init__(self):
        # 调用父类的init方法
        super().__init__()
        self.name = '小花'

    food = '鱼'

    def shout(self):
        print(super()) # <super: <class 'Cat'>, <Cat object>>
        print('喵喵') # 喵喵
        print('+++++++++++++++++++++++++++++++++++++++')
    @classmethod
    def run(cls):
        print(Animal.number)   #100
        print(super().number) #100
        print(super()) # <super: <class 'Cat'>, <Cat object>>

Cat.run()

print('=================================')
class Dog(Animal):
    def shout(self):
        # 通过super()调用父类的方法,保留父类的功能
        super().shout() #  直接赋值
        print('汪汪')

cat1 = Cat()
dog1 = Dog()
print(cat1.age) # 0
print(cat1.name) # 小花
cat1.shout() # 嗷嗷叫
dog1.shout() # 汪汪

七、init方法的重写练习

# 练习:写一个Person类,拥有属性name,age,sex。要求创建Person对象的时候必须给name和age赋值,sex可赋可不赋
#      在写一个staff类继承自Person类,要求保留Person中所有的属性,并且添加新的属性salary
#      要求创建staff类的对象的时候,只能给name赋值(必须)

class Person:
    def __init__(self,name,age,sex = 'boy'):
        self.name = name
        self.age = age
        self.sex = sex
class Staff(Person):
    def __init__(self,name):
        super().__init__(name,20)
        self.salary = 0

if __name__ == '__main__':
    p1 = Person('李涵','23','girl')
    p2 = Person('魏世强','23','boy')
    s1 = Staff('王龙')

八、运算符的重载

class Student:
    def __init__(self, name='', age=0, score=0):
        self.name = name
        self.age = age
        self.score = score

    # self:+前面的对象
    # other: +后面的对象
    def __add__(self, other):
        return self.score + other.score

    # 重载 > 符号
    # 注意:重载>和<可以只重载一个,另外一个对应的功能自动取反
    def __gt__(self, other):
        return self.age > other.age

    # 重写魔法方法__str__,用来定制对象的打印样式
    def __str__(self):
        # return '<%s.%s object at 0x%x>' % (self.__module__, self.__class__.__name__, id(self))
        # return 'Student: %s %d %d' % (self.name, self.age, self.score)
        return str(self.__dict__)[1:-1]

class Schoolchild(Student):
    def __add__(self, other):
        return self.age + other.age


if __name__ == '__main__':

    stu1 = Student('小明', 18, 90)
    stu2 = Student('老王', 29, 84)
    stu3 = Student('小花', 20, 78)

    print(stu1)  # 'name': '小明', 'age': 18, 'score': 90

    all_students = [stu1, stu2, stu3]
    all_students.sort(reverse=True)
    for stu in all_students:
        print(stu.name, stu.age, stu.score)  # 老王 29 84 ; 小花 20 78 ; 小明 18 90


    print(stu1 > stu2) # False
    print(stu1 < stu2) # True
    print(stu1 + stu2) # 174
    print(stu3 > stu1) # True

    # 父类重载了运算符,子类也能用
    c1 = Schoolchild('小明明', 8, 70)
    c2 = Schoolchild('小花花', 10, 67)
    print(c1+c2) # 18
上一篇 下一篇

猜你喜欢

热点阅读