Python进阶----类的结构(公有成员 , 私有成员(私有属性,私有方法),类方法,静态方法,属性) ,isinstance 和issubcalss ,元类(type())

Python进阶----类的结构(公有成员 , 私有成员(私有属性,私有方法),类方法,静态方法,属性) ,isinstance 和issubcalss ,元类(type())

一丶类的结构细分

    成员:

      公有属性(静态属性,对象属性),私有属性(私有静态属性,私有对象属性),私有方法,公有方法,类方法,静态方法,属性.代码如下:👇

#### 整合版
class A:
    public_attr = '公共属性'         # 公有属性(静态变量)
    __private_attr = '私有属性'      # 私有属性(私有静态变量)

    def __init__(self, name, sex):  # 初始化方法
        self.name = name            # 实例化对象时 公有属性
        self.__sex = sex            # 实例化对象时 私有属性

    def func(self):                 # 公有方法(实例化方法,默认将调用者对象传给self)
        print('in A 类  公有方法')

    def __func2(self):              # 私有方法
        print('in A 类  私有方法')


        
### 👇以下的这些 类方法, 静态方法,属性 . 只存在于类空间,不存在对象空间
    @classmethod        # 类方法
    def func3(cls):     # cls是一个参数,默认传递当前类的类名
        obj=cls()       # 实例化一个对象, 因为cls是一个类的内存地址
        print('类方法')

        
    @staticmethod       # 静态方法
    def func4():        # 默认不需要传参(根据需要,也可以传参),
        print('静态方法')

        
    @property           # 属性(将一个函数伪装成一个类成员属性,只存在于类空间)
    def func5(self):
        return 1+1
    # 测试
    def func6(self):
        
        #私有属性
        print(A.__private_attr) # 类 只能在类的内部使用类的私有属性 ,
        print(self.__sex)       # 对象 只能在类的内部使用对象的私有属性
        print(self.__private_attr)  # 对象  只能在类的内部使用对象的私有属性

     	
        # 私有方法
        self.__func2()      # 对象 只能在类的内部使用私有方法
        A.__func2('a')      # 类  只能在类的内部使用私有方法
        
        
print(A.__dict__)       # 查看当前的A类中有哪些属性和方法(变量与值的对应关系)



### 类的公有静态属性,类的外部,类的内部, 派生类都可以访问
obj_a=A('李四','男')       #实例化对象
print(A.public_attr)
print(obj_a.public_attr)



### 本类的私有属性 ,只能在 类的内部使用类的私有属性,类的外部不能使用类的私有属性
print(A.__private_attr)     # AttributeError: type object 'A' has no attribute '__private_attr'
A.func6('a')                # 只能在类中使用私有属性



### 对象的私有属性,只能在类的内部使用对象私有属性,或者类的私有属性,类的外部不能使用对象私有属性,或者类的私有属性,
obj_a=A('李四','男')       #实例化对象
print(obj_a.__sex)        # AttributeError: 'A' object has no attribute '__sex'

obj_a.func6()             # 只能在类的内部使用私有属性(对象既可以使用对象私有属性,也可以使用类的私有属性 )




### 私有方法 只能在类的内部使用,不能再类的外部使用 
obj_a=A('李四','男')
obj_a.__func2()       # 在类的外部 对象不能调用类中的私有方法
A.__func2()           # 在类的外部 类不能调用类中的私有方法
obj_a.func6()           #  只能在类中调用私有方法




###  总结 :
	# 对于  类的公有静态属性,类的外部,类的内部, 派生类都可以访问
	# 对于  类的私有静态属性,只能在类的内部使用.派生类都不可以访问

    拓展:

# # 如果想设定一些私有的,或者是不想让类外面用到  如: 密码,加密方式
# #  拓展: 私有成员除了在内部,当真访问不到吗?  ,  ( 不要使用)
class A:
     __girl='123'
     # python 中所有的私有成员: 就是在私有成员前面上 _类名而已
 print(A._A__girl)	# 可以访问类成员中的私有属性

# # python 默认对私有属性的加密方式就是在 类前面加了一个_
  # print(A.__dict__) 可以查看这个类的全部属性

二丶私有方法,私有属性

  作用:

      一些私密的方法,或私密的属性不能被查看:如(加密方法,女生的体重属性)

class A:
    public_attr = '公共属性'         # 公有属性(静态变量)
    __private_attr = '私有属性'      # 私有属性(私有静态变量)

    def __init__(self, name, sex):  # 初始化方法
        self.name = name            # 实例化对象时 公有属性
        self.__sex = sex            # 实例化对象时 私有属性

    def func(self):                 # 公有方法
        print('in A 类  公有方法')

    def __func2(self):              # 私有方法
        print('in A 类  私有方法')



    # 测试
    def func6(self):
        # 私有属性
        print(A.__private_attr) # 类 只能在类的内部使用类的私有属性 ,
        print(self.__sex)       # 对象 只能在类的内部使用对象的私有属性
        print(self.__private_attr)  # 对象  只能在类的内部使用对象的私有属性

        # 私有方法
        self.__func2()      # 对象 只能在类的内部使用私有方法
        A.__func2('a')      # 类  只能在类的内部使用私有方法
        
print(A.__dict__)       # 查看当前的A类中有哪些属性和方法(变量与值的对应关系)

### 对于 类的公有静态属性,类的外部,类的内部, 派生类都可以访问
obj_a=A('李四','男')       #实例化对象
print(A.public_attr)
print(obj_a.public_attr)

### 本类的私有属性 ,只能在 类的内部使用类的私有属性,类的外部不能使用类的私有属性
print(A.__private_attr)     # AttributeError: type object 'A' has no attribute '__private_attr'
 A.func6('a')                # 只能在类中使用私有属性

### 对象的私有属性 只能在类的内部使用对象私有属性,或者类的私有属性,类的外部不能使用对象私有属性,或者类的私有属性,
obj_a=A('李四','男')       #实例化对象
print(obj_a.__sex)        # AttributeError: 'A' object has no attribute '__sex'
obj_a.func6()             # 只能在类的内部使用私有属性(对象既可以使用对象私有属性,也可以使用类的私有属性 )


### 私有方法 只能在类的内部使用,不能再类的外部使用 
obj_a=A('李四','男')
obj_a.__func2()       # 在类的外部 对象不能调用类中的私有方法
A.__func2()           # 在类的外部 类不能调用类中的私有方法
obj_a.func6()           #  只能在类中调用私有方法

三丶类方法

  作用:

       @classmethod装饰 ,由类名直接调用的方法,通过它来传递类的属性和方法(不能传实例的属性和方法)

class B:

    @classmethod
    def func3(cls):		# 谁调用 ,cls 接收的就那个对象的从属类
        print(cls)		

class A(B):				# A类 继承B类
    num=1
    def __init__(self):通过它来传递类的属性和方法(不能传实例的属性和方法);
        pass
    def func2(self):
        print('这是实例方法')

    @classmethod # 类方法:  由类名直接调用的方法, 她会自动的将类名传给cls
    def func(cls):
        print(cls)      # 这是类名 <class '__main__.A'>
        print(cls.num)  # 调用传递类中的属性     num=1
        o=cls()         #  cls接收的是A类的内存地址, 类+()生成一个对象
        print(o)        # <__main__.A object at 0x000002BD6EA54518>
        print('这是类方法')


print(A)
A.func()        # 类调用类方法 , 默认将类名传给了cls
obj=A()         # 实例化对象
obj.func() 		# 对象也可以调用类方法, 但是会自动将其从属于的类名传给cls

obj.func3()		# <class '__main__.A'>  # 同理,调用父类的类方法,自动将当前的对象从属的类传给cls



### 总结:
	# 类方法使用装饰器@classmethod. 第一个参数必须传递当前类对象(类的内存地址),该参数名约定'cls'
	# 通过它来传递类的属性和方法(不能传实例的属性和方法);
  
   #调用:实例对象和类对象都可以调用。

  例题:

 定义一个Student类, 我要统计学生的个数

class Student:
    num=0
    def __init__(self,name):
        self.name=name
        self.count_stu()        # 调用 类方法 进行统计,实例化一次对象,调用一次

    @classmethod            # 定义类方法, 用于统计
    def count_stu(cls):
        cls.num+=1

    @classmethod            # 定义类方法,用于返回结果
    def result(cls):
        return cls.num


s1=Student('da')
s2=Student('da1')
s3=Student('da2')
s4=Student('da3')

print(Student.num)          # 调用类的num属性4
print(Student.result())     # 调用类方法,返回结果 4

四丶静态方法

  作用:

       使用装饰器@staticmethod,不依赖类, 也不依赖于对象, 静态方法是个独立的、单纯的函数 , 使结构更加清晰和合理

class A:

    def __init__(self):
        pass

    @staticmethod       # 类 和  对象  都能调用
    def static_func(a,b,c):
        print(f'{a}{b}{c}这是一个静态方法')

### 对象和类 都能调用静态方法
A.static_func(1,2,3)     # 类调用 静态方法
obj=A()
obj.static_func(1,2,3)   # 对象 调用静态方法


### 总结:
	# 使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;
 #调用:实例对象和类对象都可以调用。

  例题:

###  获取当前时间的函数。
import time

class TimeTest(object):
    def __init__(self, hour, minute, second):
        self.hour = hour
        self.minute = minute
        self.second = second

    @staticmethod
    def showTime():
        return time.strftime("%H:%M:%S", time.localtime())


print(TimeTest.showTime())
t = TimeTest(2, 10, 10)
nowTime = t.showTime()
print(nowTime)

五丶属性(特殊)

  作用:

      property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值*

      将一个类的函数定义成属性后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则

  一个静态属性property本质就是实现了get,set,delete三种方法

###### 方式 一
class Foo:
    @property
    def aaa(self):
        print('get的时候用到')
        return  'aaa'
    @aaa.setter             # 当修改property伪装成的属性的属性值,aaa.setter装饰此函数.自动调用
    def aaa(self,value):    # 函数名必须和原定义的函数名一直.
        print(value)        # value 接收的要修改的属性值()
        print('set 修改的时用到')

    @aaa.deleter
    def aaa(self):

        print('delete 删除的时候用到')

f1=Foo()
f1.aaa              #调用这个aaa伪装属性函数 get的时候用到

f1.aaa='AAA'        # 并不会在对象空间创建一个新的属性. 这是一个存在类中的伪装成属性的函数,
                    # 修改时,相当于是修改类空间中存在的这个伪装属性函数的值
print(Foo.__dict__) # 'aaa': <property object at 0x000001F9D9C76958>

del f1.aaa          # 删除


# 结果:
    get的时候运行到我
    set的时候运行到我
    delete的时候运行到我

    
    
    

###### 方式 二
class Foo:
    def get_AAA(self):
        print('get的时候运行我啊')

    def set_AAA(self,value):
        print('set的时候运行我啊')

    def delete_AAA(self):
        print('delete的时候运行我啊')
    AAA=property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应

f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA


### 调用:实例对象和类对象都可以调用。

六丶isinstance issubcalss

  isinstance(obj,M):

      判断obj对象 是否是M类,(或者M类的子类)实例化出的对象

### 判断obj对象 是否是M类,(或者M类的子类)实例化出的对象
class A:
    pass

class B(A):
    pass

class C(B):
    pass


obj = B()


print(isinstance(obj,B))	# 判断obj对象 是不是 B类或B类的子类实例化的对象
print(isinstance(obj,A))    # 判断obj对象 是不是 A类或A类的子类实例化对象
print(isinstance(obj,object))    # 判断 obj 是不是 object类 或object的子类实例化对象

print(isinstance(obj,C)) 	# C类不是B 的子类	False  ?????

  issubcalss(M,N):

      判断 M类 是不是从属于 N 类 或N类的子类(派生类)

### 判断 M类 是不是从属于 N 类 或N类的子类
class A:
    pass

class B(A):
    pass

class C(B):
    pass

class D(C):
    pass

print(issubclass(B,A))	# 判断 B类 是不是从属于 A 类 或A类的派生类
print(issubclass(C,A))	# 判断 C类 是不是从属于 A 类 或A类的派生类
print(issubclass(C,object))	# 判断 C类 是不是从属于 object 类 或object类的派生类

print(issubclass(C,D))	# 判断 C类 是不是从属于D 类 或D类的派生类False

七丶元类type(name, bases, dict)

  元类: 就是能够实例化所有类包括object类, 同时还继承object类,(有待深入研究)

      name -- 类的名称。

      bases -- 基类的元组。

      dict -- 字典,类内定义的命名空间变量。

       type元类是获取该对象从属于的类,而type类比较特殊,Python原则是:一切皆对象,其实类也可以理解为'对象',而type元类又称作构建类,python中大多数内置的类(包括object)以及自己定义的类,都是由type元类创造的。

      而type类与object类之间的关系比较独特:object是type类的实例,而type类是object类的子类,这种关系比较神奇无法使用python的代码表述,因为定义其中一个之前另一个必须存在。所以这个只作为了解。

## 案例一:
from collections import Iterable
from collections import Iterator
s1='absad'
str()
print(type(s1)) # 判断的是对象从属于哪个类


# type  也叫元类   , 一切皆对象.   一个类也是一个对象, 那么这个(类)对象肯定是由类实例化出来的
# 在python中你创建的所有类, 以及大部分list str 等等这些类,都是从type元类实例化来的




## 案例二:
print(type('abc'))
print(type(True))
print(type(100))
print(type([1, 2, 3]))
print(type({'name': '太白金星'}))
print(type((1,2,3)))
print(type(object))

class A:
    pass

print(isinstance(object,type))	
print(isinstance(A, type))
posted @ 2019-07-11 22:25  染指未来  阅读(344)  评论(0编辑  收藏  举报